Hi,

thanks for your reply.  Attached is a new patch against HEAD taking your
comments into consideration.

Note that the static int firsttime hack can go away as soon as the
repeated config reads in main() are consolidated.

thanks,
-serge

On Thu, 2004-02-19 at 10:04, Joe Orton wrote:
...
> I think that stuff be avoided by using the:
> 
>     if (ssl_config_global_isfixed(mc)) {
>         return NULL;
>     }
> 
> trick like the other ssl_cmd_* functions?  There are code formatting
> issues through the rest of the patch, otherwise looks OK - a patch
> against HEAD would be ideal of course...
> 
> > +const char *ssl_cmd_SSLCryptoDeviceCtrl(cmd_parms *cmd,
> > +                                   void *dcfg,
> > +                                   const char *arg,
> > +                                   const char *prepost)
> > +{
> ...
> > +    colon = strchr(arg, ':');
> 
> should be ap_strchr_c() to avoid losing const-ness.
> 
> > +static int internal_ctrl_cb(void *r, const char *k, const char *v)
> 
> could do with some meaningful parameter names :)
> 
> Regards,
> 
> joe
-- 
=======================================================
Serge Hallyn
Security Software Engineer, IBM Linux Technology Center
[EMAIL PROTECTED]
Index: modules/ssl/mod_ssl.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/ssl/mod_ssl.c,v
retrieving revision 1.95
diff -u -r1.95 mod_ssl.c
--- modules/ssl/mod_ssl.c	9 Feb 2004 20:29:22 -0000	1.95
+++ modules/ssl/mod_ssl.c	23 Feb 2004 19:46:50 -0000
@@ -86,6 +86,9 @@
     SSL_CMD_SRV(CryptoDevice, TAKE1,
                 "SSL external Crypto Device usage "
                 "(`builtin', `...')")
+    SSL_CMD_SRV(CryptoDeviceCtrl, TAKE12,
+                "SSL external Crypto Device custom control commands "
+                "(`cmd[:arg] [pre|post]')")
 #endif
     SSL_CMD_SRV(RandomSeed, TAKE23,
                 "SSL Pseudo Random Number Generator (PRNG) seeding source "
Index: modules/ssl/mod_ssl.h
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/ssl/mod_ssl.h,v
retrieving revision 1.148
diff -u -r1.148 mod_ssl.h
--- modules/ssl/mod_ssl.h	9 Feb 2004 20:29:22 -0000	1.148
+++ modules/ssl/mod_ssl.h	23 Feb 2004 19:46:50 -0000
@@ -368,6 +368,7 @@
     apr_hash_t     *tPrivateKey;
 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
     const char     *szCryptoDevice;
+    apr_table_t    *tCryptoDeviceCtrl;
 #endif
     struct {
         void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10;
@@ -482,6 +483,7 @@
 const char  *ssl_cmd_SSLMutex(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
+const char  *ssl_cmd_SSLCryptoDeviceCtrl(cmd_parms *, void *, const char *, const char *);
 const char  *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
 const char  *ssl_cmd_SSLEngine(cmd_parms *, void *, const char *);
 const char  *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *);
Index: modules/ssl/ssl_engine_config.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/ssl/ssl_engine_config.c,v
retrieving revision 1.88
diff -u -r1.88 ssl_engine_config.c
--- modules/ssl/ssl_engine_config.c	9 Feb 2004 20:29:22 -0000	1.88
+++ modules/ssl/ssl_engine_config.c	23 Feb 2004 19:46:50 -0000
@@ -74,6 +74,7 @@
     mc->tPublicCert            = apr_hash_make(pool);
 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
     mc->szCryptoDevice         = NULL;
+    mc->tCryptoDeviceCtrl      = apr_table_make(mc->pPool, 10);
 #endif
 
     memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
@@ -509,6 +510,65 @@
 
     return NULL;
 }
+
+const char *ssl_cmd_SSLCryptoDeviceCtrl(cmd_parms *cmd,
+                                        void *dcfg,
+                                        const char *arg,
+                                        const char *prepost)
+{
+    SSLModConfigRec *mc = myModConfig(cmd->server);
+    const char *err;
+    ENGINE *e;
+    char *colon, *value, *converted_val;
+
+    if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
+        return err;
+    }
+
+    if (ssl_config_global_isfixed(mc)) {
+        return NULL;
+    }
+
+    if ((e = ENGINE_by_id(mc->szCryptoDevice)) == NULL) {
+        err = "SSLCryptoDeviceCtrl: Must follow a valid engine";
+        goto end;
+    }
+    if (!ENGINE_ctrl(e, ENGINE_CTRL_HAS_CTRL_FUNCTION, 0, NULL, NULL)) {
+        err = "SSLCryptoDeviceCtrl: The engine has no 'ctrl' handler";
+        goto end;
+    }
+    if(prepost) {
+        if(strcmp(prepost, "pre") && strcmp(prepost, "post")) {
+            err = "SSLCryptoDeviceCtrl: Only 'pre' and 'post are valid options";
+            goto end;
+        }
+    } else
+        prepost = "pre";
+    /* Now separate out the argument into name:value (or name:'NULL' if there is
+     * no value). */
+    colon = ap_strchr_c(arg, ':');
+    if(colon) {
+        *colon = '\0';
+        value = colon + 1;
+    } else
+        value = NULL;
+    if (ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FROM_NAME, 0, arg, NULL) < 0) {
+        err = "SSLCryptoDeviceCtrl: The engine doesn't recognise that command";
+        goto end;
+    }
+    if(!value)
+        converted_val = prepost;
+    else {
+        converted_val = apr_palloc(cmd->pool, strlen(value) + 5);
+        sprintf(converted_val, "%s%s", prepost, value);
+    }
+    apr_table_set(mc->tCryptoDeviceCtrl, arg, converted_val);
+
+end:
+    if(e)
+        ENGINE_free(e);
+    return err;
+ }
 #endif
 
 const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
Index: modules/ssl/ssl_engine_init.c
===================================================================
RCS file: /home/cvspublic/httpd-2.0/modules/ssl/ssl_engine_init.c,v
retrieving revision 1.123
diff -u -r1.123 ssl_engine_init.c
--- modules/ssl/ssl_engine_init.c	9 Feb 2004 20:29:22 -0000	1.123
+++ modules/ssl/ssl_engine_init.c	23 Feb 2004 19:46:50 -0000
@@ -313,10 +313,46 @@
  * a hardware accellerator card for crypto operations.
  */
 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
+
+struct engine_dummy {
+    ENGINE *e;
+    int ispost;
+    const char *bailed;
+};
+
+static int internal_ctrl_cb(void *engine_wrapper,
+                            const char *cmd_string,
+                            const char *cmd_arg)
+{
+    struct engine_dummy *d = (struct engine_dummy *)engine_wrapper;
+
+    if (strncmp(cmd_arg, "post", 4) == 0) {
+        /* This key-value pair is for "post" operation */
+        if (!d->ispost)
+            return 1;
+        cmd_arg += 4;
+    } else {
+        /* THis key-value pair is for "pre" operation */
+        if (d->ispost)
+            return 1;
+        cmd_arg += 3;
+    }
+    if (strlen(cmd_arg) == 0)
+        cmd_arg = NULL;
+
+    if (!ENGINE_ctrl_cmd_string(d->e, cmd_string, cmd_arg, 0)) {
+        d->bailed = cmd_string;
+        return 0;
+    }
+    return 1;
+}
+
 void ssl_init_Engine(server_rec *s, apr_pool_t *p)
 {
     SSLModConfigRec *mc = myModConfig(s);
     ENGINE *e;
+    struct engine_dummy d;
+    static int firsttime = 1;
 
     if (mc->szCryptoDevice) {
         if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
@@ -326,6 +362,20 @@
             ssl_die();
         }
 
+        if (!firsttime) {
+            d.e = e;
+            d.ispost = 0;
+            d.bailed = NULL;
+            apr_table_do(internal_ctrl_cb, &d, mc->tCryptoDeviceCtrl, NULL);
+            if (d.bailed) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                        "Init: Failed on command '%s'", d.bailed);
+                ssl_die();
+            }
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                "Init: Succeeded (pre)\n");
+        }
+
         if (strEQ(mc->szCryptoDevice, "chil")) {
             ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
         }
@@ -337,7 +387,21 @@
             ssl_die();
         }
 
+        if (!firsttime) {
+            d.ispost = 1;
+            apr_table_do(internal_ctrl_cb, &d, mc->tCryptoDeviceCtrl, NULL);
+            if (d.bailed) {
+                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                        "Init: Failed on command '%s'", d.bailed);
+                ssl_die();
+            }
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                "Init: Succeeded (post)\n");
+        }
+
         ENGINE_free(e);
+
+        firsttime = 0;
     }
 }
 #endif

Reply via email to