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: