]> granicus.if.org Git - apache/commitdiff
reuse vhost keys for asn1 tables where keys are allocated out
authorDoug MacEachern <dougm@apache.org>
Thu, 28 Feb 2002 01:30:18 +0000 (01:30 +0000)
committerDoug MacEachern <dougm@apache.org>
Thu, 28 Feb 2002 01:30:18 +0000 (01:30 +0000)
of s->process->pool to prevent "leaking" each time we format
a vhost key.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93616 13f79535-47bb-0310-9956-ffa450edef68

modules/ssl/mod_ssl.h
modules/ssl/ssl_engine_config.c
modules/ssl/ssl_engine_pphrase.c

index 6055fe7ddc214845aacfb6486dfa72469ffc8a4c..bbdf46ce0684d655270831c2368fee96d1a60d1c 100644 (file)
@@ -516,6 +516,7 @@ typedef struct {
     apr_lock_t     *pMutex;
     apr_array_header_t   *aRandSeed;
     int             nScoreboardSize; /* used for builtin random seed */
+    apr_hash_t     *tVHostKeys;
     apr_hash_t     *tTmpKeys;
     void           *pTmpKeys[SSL_TKPIDX_MAX];
     apr_hash_t     *tPublicCert;
index fd291fec4b52fe500ae8e299fa4f8eb697ff9d96..9c4a3f22111bf679e5f91b1dbc7cad67ef4124cf 100644 (file)
@@ -101,6 +101,7 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s)
         mc->szMutexFile            = NULL;
         mc->pMutex                 = NULL;
         mc->aRandSeed              = apr_array_make(pPool, 4, sizeof(ssl_randseed_t));
+        mc->tVHostKeys             = apr_hash_make(pPool);
         mc->tPrivateKey            = apr_hash_make(pPool);
         mc->tPublicCert            = apr_hash_make(pPool);
         mc->tTmpKeys               = apr_hash_make(pPool);
index 0a7c0c92689a8d6366e0b1895ce067e534c04f70..a7a7651fe0cad8aced2e480f2cbbe9b2592a5b1e 100644 (file)
@@ -90,6 +90,40 @@ static apr_status_t exists_and_readable(char *fname, apr_pool_t *pool, apr_time_
     return APR_SUCCESS;
 }
 
+/*
+ * reuse vhost keys for asn1 tables where keys are allocated out
+ * of s->process->pool to prevent "leaking" each time we format
+ * a vhost key.  since the key is stored in a table with lifetime
+ * of s->process->pool, the key needs to have the same lifetime.
+ *
+ * XXX: probably seems silly to use a hash table with keys and values
+ * being the same, but it is easier than doing a linear search
+ * and will make it easier to remove keys if needed in the future.
+ * also have the problem with apr_array_header_t that if we
+ * underestimate the number of vhost keys when we apr_array_make(),
+ * the array will get resized when we push past the initial number
+ * of elts.  this resizing in the s->process->pool means "leaking"
+ * since apr_array_push() will apr_alloc arr->nalloc * 2 elts,
+ * leaving the original arr->elts to waste.
+ */
+static char *asn1_table_vhost_key(SSLModConfigRec *mc, apr_pool_t *p,
+                                  char *id, char *an)
+{
+    /* 'p' pool used here is cleared on restarts */
+    char *key = apr_psprintf(p, "%s:%s", id, an);
+    void *keyptr = apr_hash_get(mc->tVHostKeys, key,
+                                APR_HASH_KEY_STRING);
+
+    if (!keyptr) {
+        /* make a copy out of s->process->pool */
+        keyptr = apr_pstrdup(mc->pPool, key);
+        apr_hash_set(mc->tVHostKeys, keyptr,
+                     APR_HASH_KEY_STRING, keyptr);
+    }
+
+    return (char *)keyptr;
+}
+
 /*  _________________________________________________________________
 **
 **  Pass Phrase and Private Key Handling
@@ -199,7 +233,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
              * certificate is actually used to configure mod_ssl's per-server
              * configuration structures).
              */
-            cp = apr_psprintf(mc->pPool, "%s:%s", cpVHostID, an);
+            cp = asn1_table_vhost_key(mc, p, cpVHostID, an);
             length = i2d_X509(pX509Cert, NULL);
             ucp = ssl_asn1_table_set(mc->tPublicCert, cp, length);
             (void)i2d_X509(pX509Cert, &ucp); /* 2nd arg increments */
@@ -426,7 +460,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
              * because the SSL library uses static variables inside a
              * RSA structure which do not survive DSO reloads!)
              */
-            cp = apr_psprintf(mc->pPool, "%s:%s", cpVHostID, an);
+            cp = asn1_table_vhost_key(mc, p, cpVHostID, an);
             length = i2d_PrivateKey(pPrivateKey, NULL);
             ucp = ssl_asn1_table_set(mc->tPrivateKey, cp, length);
             (void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */