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:

Reply via email to