]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
*) core: Adding SSL related inquiry functions to the server API.
authorStefan Eissing <icing@apache.org>
Tue, 23 Feb 2021 15:08:24 +0000 (15:08 +0000)
committerStefan Eissing <icing@apache.org>
Tue, 23 Feb 2021 15:08:24 +0000 (15:08 +0000)
     These function are always available, even when no module providing
     SSL is loaded. They provide their own "shadowing" implementation for
     the optional functions of similar name that mod_ssl and impersonators
     of mod_ssl provide.
     This enables loading of several SSL providing modules when all but
     one of them registers itself into the new hooks. Two old-style SSL
     modules will not work, as they replace the others optional functions
     with their own.
     Modules using the old-style optional functions will continue to work
     as core supplies its own versions of those.
     The following has been added so far:
     - ap_ssl_conn_is_ssl() to query if a connection is using SSL.
     - ap_ssl_var_lookup() to query SSL related variables for a
       server/connection/request.
     - Hooks for 'ssl_conn_is_ssl' and 'ssl_var_lookup' where modules
       providing SSL can install their own value supplying functions.

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

changes-entries/core_ssl_functions.txt [new file with mode: 0644]
include/ap_mmn.h
include/http_protocol.h
server/core.c
server/protocol.c

diff --git a/changes-entries/core_ssl_functions.txt b/changes-entries/core_ssl_functions.txt
new file mode 100644 (file)
index 0000000..fdcbad4
--- /dev/null
@@ -0,0 +1,18 @@
+  *) core: Adding SSL related inquiry functions to the server API.
+     These function are always available, even when no module providing
+     SSL is loaded. They provide their own "shadowing" implementation for
+     the optional functions of similar name that mod_ssl and impersonators
+     of mod_ssl provide.
+     This enables loading of several SSL providing modules when all but
+     one of them registers itself into the new hooks. Two old-style SSL
+     modules will not work, as they replace the others optional functions
+     with their own.
+     Modules using the old-style optional functions will continue to work
+     as core supplies its own versions of those.
+     The following has been added so far:
+     - ap_ssl_conn_is_ssl() to query if a connection is using SSL.
+     - ap_ssl_var_lookup() to query SSL related variables for a 
+       server/connection/request.
+     - Hooks for 'ssl_conn_is_ssl' and 'ssl_var_lookup' where modules
+       providing SSL can install their own value supplying functions.
+     [Stefan Eissing]
index 1d38b110eb67fc1246f9b7c1d66188e71b562bdc..f6a6d2597ab0a741d9eecb6d466452ee0b54b561 100644 (file)
  *                         ap_proxy_read_input().
  * 20200705.4 (2.5.1-dev)  Add ap_get_status_line_ex()
  * 20201214.0 (2.5.1-dev)  Axe struct core_net_rec
+ * 20201214.1 (2.5.1-dev)  Add ap_ssl_conn_is_ssl()/ap_ssl_var_lookup() and hooks
  */
 
 #define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
 #ifndef MODULE_MAGIC_NUMBER_MAJOR
 #define MODULE_MAGIC_NUMBER_MAJOR 20201214
 #endif
-#define MODULE_MAGIC_NUMBER_MINOR 0             /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 1             /* 0...n */
 
 /**
  * Determine if the server's current MODULE_MAGIC_NUMBER is at least a
index 9c9cb952b23aa52a32e56c6595b937a1ce344af1..5c57a851814855dd2974618d5c3e5294823c10fa 100644 (file)
@@ -1048,6 +1048,66 @@ AP_DECLARE(void) ap_finalize_sub_req_protocol(request_rec *sub_r);
 AP_DECLARE(void) ap_send_interim_response(request_rec *r, int send_headers);
 
 
+/**
+ * Setup optional functions for ssl related queries so that functions
+ * registered by old-style SSL module functions are interrogated by the 
+ * the new ap_is_ssl() and friends. Installs own optional functions, so that
+ * old modules looking for these find one and get the correct results (shadowing).
+ * 
+ * Needs to run in core's very early POST_CONFIG hook.
+ * Modules providing such functions register their own optionals during 
+ * register_hooks(). Modules using such functions retrieve them often 
+ * in their own post-config or in the even later retrieval hook. When shadowing
+ * other modules functions, core's early post-config is a good time. 
+ * @param pool The pool to use for allocations
+ */
+AP_DECLARE(void) ap_setup_ssl_optional_fns(apr_pool_t *pool);
+
+/**
+ * This hook allows modules that manage SSL connection to register their
+ * inquiry function for checking if a connection is using SSL from them.
+ * @param c The current connection
+ * @return OK if the connection is using SSL, DECLINED if not.
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(int,ssl_conn_is_ssl,(conn_rec *c))
+
+/**
+ * This hook allows modules to look up SSL related variables for a 
+ * server/connection/request, depending on what they inquire. Some 
+ * variables will only be available for a connection/request, for example.
+ * @param p The pool to allocate a returned value in, MUST be provided
+ * @param s The server to inquire a value for, maybe NULL
+ * @param c The current connection, maybe NULL
+ * @param r The current request, maybe NULL
+ * @param name The name of the variable to retrieve, MUST be provided
+ * @return value or the variable or NULL if not provided/available
+ * @ingroup hooks
+ */
+AP_DECLARE_HOOK(const char *,ssl_var_lookup,
+    (apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *name))
+
+/**
+ * Return != 0 iff the connection is encrypted with SSL.
+ * @param c the connection
+ */
+AP_DECLARE(int) ap_ssl_conn_is_ssl(conn_rec *c);
+
+/**
+ * Lookup an SSL related variable for the server/connection/request or a global
+ * value when all those parameters are set to NULL. Pool and name must always be
+ * provided and the returned value (if not NULL) will be allocated fromt he pool.
+ * @param p The pool to allocate a returned value in, MUST be provided
+ * @param s The server to inquire a value for, maybe NULL
+ * @param c The current connection, maybe NULL
+ * @param r The current request, maybe NULL
+ * @param name The name of the variable to retrieve, MUST be provided
+ * @return value or the variable or NULL if not provided/available
+ */
+AP_DECLARE(const char *) ap_ssl_var_lookup(apr_pool_t *p, server_rec *s,
+                                           conn_rec *c, request_rec *r,
+                                           const char *name);                                           
+
 #ifdef __cplusplus
 }
 #endif
index e3d4b7718330ed7eac610ece6f09355e39cc386f..44d832b07a3a62cc8473142cec02c5a1573716c4 100644 (file)
@@ -5312,6 +5312,7 @@ static int core_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *pte
     set_banner(pconf);
     ap_setup_make_content_type(pconf);
     ap_setup_auth_internal(ptemp);
+    ap_setup_ssl_optional_fns(pconf);
     if (!sys_privileges) {
         ap_log_error(APLOG_MARK, APLOG_CRIT, 0, NULL, APLOGNO(00136)
                      "Server MUST relinquish startup privileges before "
index 626560a64f6401c45ed1ce2e9bd3719d457e23f4..afd76aa07c1d81091294df04fb3a9f8fe7dc5ccf 100644 (file)
@@ -70,6 +70,8 @@ APR_HOOK_STRUCT(
     APR_HOOK_LINK(protocol_propose)
     APR_HOOK_LINK(protocol_switch)
     APR_HOOK_LINK(protocol_get)
+    APR_HOOK_LINK(ssl_conn_is_ssl)
+    APR_HOOK_LINK(ssl_var_lookup)
 )
 
 AP_DECLARE_DATA ap_filter_rec_t *ap_old_write_func = NULL;
@@ -2630,6 +2632,71 @@ AP_DECLARE(int) ap_is_allowed_protocol(conn_rec *c, request_rec *r,
     return !strcmp(AP_PROTOCOL_HTTP1, protocol);
 }
 
+APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *));
+static APR_OPTIONAL_FN_TYPE(ssl_is_https) *module_ssl_is_https;
+
+static int ssl_is_https(conn_rec *c) 
+{
+    /* Someone retrieved the optional function., not knowning about the
+     * new API. We redirect them to what they should have inoked. */
+    return ap_ssl_conn_is_ssl(c);
+}
+
+AP_DECLARE(int) ap_ssl_conn_is_ssl(conn_rec *c)
+{
+    int r = (ap_run_ssl_conn_is_ssl(c) == OK);
+    if (r == 0 && module_ssl_is_https) {
+        r = module_ssl_is_https(c);
+    }
+    return r;
+}
+
+APR_DECLARE_OPTIONAL_FN(const char *, ssl_var_lookup,
+                        (apr_pool_t *p, server_rec *s,
+                         conn_rec *c, request_rec *r,
+                         const char *name))
+    AP_FN_ATTR_NONNULL((1, 2, 5)) AP_FN_ATTR_WARN_UNUSED_RESULT;
+static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *module_ssl_var_lookup;
+    
+static const char *ssl_var_lookup(apr_pool_t *p, server_rec *s,
+                                  conn_rec *c, request_rec *r,
+                                  const char *name)
+{
+    /* Someone retrieved the optional function., not knowning about the
+     * new API. We redirect them to what they should have inoked. */
+    return ap_ssl_var_lookup(p, s, c, r, name);
+}
+
+AP_DECLARE(const char *) ap_ssl_var_lookup(apr_pool_t *p, server_rec *s,
+                                           conn_rec *c, request_rec *r,
+                                           const char *name)
+{
+    const char *val = ap_run_ssl_var_lookup(p, s, c, r, name);
+    if (val == NULL && module_ssl_is_https) {
+        val = module_ssl_var_lookup(p, s, c, r, name);
+    }
+    return val;
+}
+
+AP_DECLARE(void) ap_setup_ssl_optional_fns(apr_pool_t *pool)
+{
+    /* Run as core's very early 'post config' hook, check for any already
+     * installed optional functions related to SSL and save them. Install
+     * our own instances that invoke the new hooks. */
+    APR_OPTIONAL_FN_TYPE(ssl_is_https) *fn_is_https;
+    APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *fn_ssl_var_lookup;
+    
+    fn_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
+    module_ssl_is_https = (fn_is_https 
+        && fn_is_https != ssl_is_https)? fn_is_https : NULL;
+    APR_REGISTER_OPTIONAL_FN(ssl_is_https);
+
+    fn_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
+    module_ssl_var_lookup = (fn_ssl_var_lookup 
+        && fn_ssl_var_lookup != ssl_var_lookup)? fn_ssl_var_lookup : NULL;
+    APR_REGISTER_OPTIONAL_FN(ssl_var_lookup);
+}
+
 
 AP_IMPLEMENT_HOOK_VOID(pre_read_request,
                        (request_rec *r, conn_rec *c),
@@ -2656,3 +2723,8 @@ AP_IMPLEMENT_HOOK_RUN_FIRST(int,protocol_switch,
                             (c, r, s, protocol), DECLINED)
 AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,protocol_get,
                             (const conn_rec *c), (c), NULL)
+AP_IMPLEMENT_HOOK_RUN_FIRST(int, ssl_conn_is_ssl, 
+                            (conn_rec *c), (c), DECLINED)
+AP_IMPLEMENT_HOOK_RUN_FIRST(const char *,ssl_var_lookup,
+        (apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, const char *name),
+        (p, s, c, r, name), NULL)