diff options
author | Martin Kraemer <martin@apache.org> | 2005-07-22 14:11:55 +0200 |
---|---|---|
committer | Martin Kraemer <martin@apache.org> | 2005-07-22 14:11:55 +0200 |
commit | 4c8c57327534587c0b56f007e24616d373cb0963 (patch) | |
tree | 6d1fb8664ea9318ca0f5c2116e2de4e4968f7c92 /modules/metadata/mod_setenvif.c | |
parent | build. (diff) | |
download | apache2-4c8c57327534587c0b56f007e24616d373cb0963.tar.xz apache2-4c8c57327534587c0b56f007e24616d373cb0963.zip |
Allow extraction of the values of SSL certificate extensions into
environment variables, so that their value can be used by any
module that is aware of environment variables, as in:
SetEnvIf OID("2.16.840.1.113730.1.13") "(.*) Generated (Certificate)" ca=$1
sets
ca=TinyCA
if the cert was issued by TinyCA.
Similarly,
SetenvIf OID("2.16.840.1.113730.1.13") "(.*)" NetscapeComment=$1
will set $NetscapeComment to the whole string.
It is technically allowed to have multiple instances of an extension
field, all with the same oid. In this case, the environment variable
will be set to the list of all fields, separated by commas.
The [PATCH] uses a cross-module call from mod_setenvif to
mod_ssl (the latter may also be missing: in this case the
variable will never be set). It calls a common function
in the ssl module that is also used for the SSLRequire
directive's test.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@220307 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/metadata/mod_setenvif.c')
-rw-r--r-- | modules/metadata/mod_setenvif.c | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/modules/metadata/mod_setenvif.c b/modules/metadata/mod_setenvif.c index f07a9f5925..0010e3a943 100644 --- a/modules/metadata/mod_setenvif.c +++ b/modules/metadata/mod_setenvif.c @@ -102,7 +102,8 @@ enum special { SPECIAL_REQUEST_URI, SPECIAL_REQUEST_METHOD, SPECIAL_REQUEST_PROTOCOL, - SPECIAL_SERVER_ADDR + SPECIAL_SERVER_ADDR, + SPECIAL_OID_VALUE }; typedef struct { char *name; /* header name */ @@ -120,6 +121,12 @@ typedef struct { } sei_cfg_rec; module AP_MODULE_DECLARE_DATA setenvif_module; +#if (MODULE_MAGIC_NUMBER_MAJOR > 20020903) +#include "mod_ssl.h" +#else +APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, ssl_extlist_by_oid, (request_rec *r, const char *oidstr)); +#endif +static APR_OPTIONAL_FN_TYPE(ssl_extlist_by_oid) *ssl_extlist_by_oid_func = NULL; /* * These routines, the create- and merge-config functions, are called @@ -345,6 +352,31 @@ static const char *add_setenvif_core(cmd_parms *cmd, void *mconfig, else if (!strcasecmp(fname, "server_addr")) { new->special_type = SPECIAL_SERVER_ADDR; } + else if (!strncasecmp(fname, "oid(",4)) { + ap_regmatch_t match[AP_MAX_REG_MATCH]; + + new->special_type = SPECIAL_OID_VALUE; + + /* Syntax check and extraction of the OID as a regex: */ + new->pnamereg = ap_pregcomp(cmd->pool, + "^oid\\(\"?([0-9.]+)\"?\\)$", + (AP_REG_EXTENDED // | AP_REG_NOSUB + | AP_REG_ICASE)); + /* this can never happen, as long as pcre works: + if (new->pnamereg == NULL) + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "OID regex could not be compiled.", NULL); + */ + if (ap_regexec(new->pnamereg, fname, AP_MAX_REG_MATCH, match, 0) == AP_REG_NOMATCH) { + return apr_pstrcat(cmd->pool, cmd->cmd->name, + "OID syntax is: oid(\"1.2.3.4.5\"); error in: ", + fname, NULL); + } + new->pnamereg = NULL; + /* The name field is used for the stripped oid string */ + new->name = fname = apr_pstrdup(cmd->pool, fname+match[1].rm_so); + fname[match[1].rm_eo - match[1].rm_so] = '\0'; + } else { new->special_type = SPECIAL_NOT; /* Handle fname as a regular expression. @@ -475,6 +507,8 @@ static int match_headers(request_rec *r) * same header. Remember we don't need to strcmp the two header * names because we made sure the pointers were equal during * configuration. + * In the case of SPECIAL_OID_VALUE values, each oid string is + * dynamically allocated, thus there are no duplicates. */ if (b->name != last_name) { last_name = b->name; @@ -498,6 +532,34 @@ static int match_headers(request_rec *r) case SPECIAL_REQUEST_PROTOCOL: val = r->protocol; break; + case SPECIAL_OID_VALUE: + /* If mod_ssl is not loaded, the accessor function is NULL */ + if (ssl_extlist_by_oid_func != NULL) + { + apr_array_header_t *oid_array; + char **oid_value; + int j, len = 0; + char *retval = NULL; + + /* The given oid can occur multiple times. Concatenate the values */ + if ((oid_array = ssl_extlist_by_oid_func(r, b->name)) != NULL) { + oid_value = (char **) oid_array->elts; + /* pass 1: determine the size of the string */ + for (len=j=0; j < oid_array->nelts; j++) { + len += strlen(oid_value[j]) + 1; /* +1 for ',' or terminating NIL */ + } + retval = apr_palloc(r->pool, len); + /* pass 2: fill the string */ + for (j=0; j < oid_array->nelts; j++) { + if (j > 0) { + strcat(retval, ","); + } + strcat(retval, oid_value[j]); + } + } + val = retval; + } + break; case SPECIAL_NOT: if (b->pnamereg) { /* Matching headers_in against a regex. Iterate through @@ -568,10 +630,19 @@ static int match_headers(request_rec *r) return DECLINED; } +static int +setenvif_post_config() +{ + ssl_extlist_by_oid_func = APR_RETRIEVE_OPTIONAL_FN(ssl_extlist_by_oid); + return OK; +} + static void register_hooks(apr_pool_t *p) { ap_hook_header_parser(match_headers, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_post_read_request(match_headers, NULL, NULL, APR_HOOK_MIDDLE); + /* post config handling */ + ap_hook_post_config(setenvif_post_config, NULL, NULL, APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA setenvif_module = |