On Fri, Aug 05, 2005 at 08:00:01PM +0200, Martin Kraemer wrote: > On Tue, Aug 02, 2005 at 07:14:10PM +0200, Martin Kraemer wrote: > > I wanted something like > > > > SSLRequire "committers" in SSLPeerExtList("1.3.6.1.4.1.18060.1"); > > > > to mean "at least one extension with an OID of > > 1.3.6.1.4.1.18060.1 with a value of 'committers' exists in the > > client cert". > > I'll be on vacation next week, and will send in another patch after > that.
OK, hope you had a good holiday. I wasn't trying to argue about the semantics just to nitpick the naming. Having "SSL" in the SSLRequire function is redundant, but not in the context of mod_setenvif. So, my preference is: SSLRequire "committers" in PeerExtList("1.3.6.1.4.1.18060.1"); SetEnvIf SSL_PeerExtList("etc") ... I just went to write a test case for the SetEnvIf function, and there seems to be a rather annoying fundamental problem: the match_headers hooks runs too early to be useful for this when doing per-dir client cert negotiation. Attached the patch I have for mod_setenvif to clean it up and adopt the naming above; untested so far as I'm blocked by the fact that it doesn't work for per-dir negotiation. joe
Index: modules/metadata/mod_setenvif.c =================================================================== --- modules/metadata/mod_setenvif.c (revision 232271) +++ modules/metadata/mod_setenvif.c (working copy) @@ -104,7 +104,7 @@ SPECIAL_REQUEST_METHOD, SPECIAL_REQUEST_PROTOCOL, SPECIAL_SERVER_ADDR, - SPECIAL_OID_VALUE + SPECIAL_SSL_PEEREXTLIST }; typedef struct { char *name; /* header name */ @@ -349,30 +349,30 @@ 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]; + else if (!strncasecmp(fname, "ssl_peerextlist(", + sizeof("ssl_peerextlist(") - 1)) { + const char *oid, *oidend; - new->special_type = SPECIAL_OID_VALUE; + new->special_type = SPECIAL_SSL_PEEREXTLIST; - /* 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) { + oid = fname + strlen("ssl_peerextlist("); + oidend = ap_strchr_c(oid, ')'); + + /* skip over quotes if present */ + if (oid[0] == '"') { + oid++; + } + if (oidend && oidend[-1] == '"') { + oidend--; + } + + if (!oidend || oidend <= oid) { return apr_pstrcat(cmd->pool, cmd->cmd->name, - "OID syntax is: oid(\"1.2.3.4.5\"); error in: ", - fname, NULL); + "invalid ssl_peerextlist() syntax 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'; + + new->name = apr_pstrmemdup(cmd->pool, oid, oidend - oid); } else { new->special_type = SPECIAL_NOT; @@ -504,8 +504,10 @@ * 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. + * + * In the case of SPECIAL_SSL_PEEREXTLIST values, each + * extension list is dynamically allocated, thus there are no + * duplicates. */ if (b->name != last_name) { last_name = b->name; @@ -529,32 +531,19 @@ case SPECIAL_REQUEST_PROTOCOL: val = r->protocol; break; - case SPECIAL_OID_VALUE: + case SPECIAL_SSL_PEEREXTLIST: /* 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; + if (ssl_extlist_by_oid_func) { + apr_array_header_t *exts; - /* 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]); - } + ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, + "peerextlist: retrieving for oid [%s]", + b->name); + + exts = ssl_extlist_by_oid_func(r, b->name); + if (exts) { + val = apr_array_pstrcat(r->pool, exts, ','); } - val = retval; } break; case SPECIAL_NOT: