]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
On the trunk:
authorStefan Eissing <icing@apache.org>
Fri, 8 Sep 2017 14:55:04 +0000 (14:55 +0000)
committerStefan Eissing <icing@apache.org>
Fri, 8 Sep 2017 14:55:04 +0000 (14:55 +0000)
mod_md: v0.9.2: new directive 'MDHttpProxy' to define a proxy for outgoing connection,
some minor bugfixes, twiddle the build system to avoid non-pic code generation.

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

20 files changed:
CHANGES
modules/md/Makefile.in
modules/md/config2.m4
modules/md/md_acme.c
modules/md/md_acme.h
modules/md/md_acme_authz.c
modules/md/md_acme_drive.c
modules/md/md_cmd.h
modules/md/md_cmd_main.c
modules/md/md_core.c
modules/md/md_curl.c
modules/md/md_http.c
modules/md/md_http.h
modules/md/md_reg.c
modules/md/md_reg.h
modules/md/md_util.c
modules/md/md_version.h
modules/md/mod_md.c
modules/md/mod_md_config.c
modules/md/mod_md_config.h

diff --git a/CHANGES b/CHANGES
index 4a70dede5cf7c98d37e3074b41db6252e78313f6..12363b3c7e670be78bada7da298511d63e126add 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_md: v0.9.2: new directive 'MDHttpProxy' to define a proxy for outgoing connection,
+     some minor bugfixes, twiddle the build system to avoid non-pic code generation.
+     [Stefan Eissing]
+  
   *) mod_ssl: Adding option to set a list of addr:port specs, as used in VirtualHosts
      to enable SSLEngine for all matching hosts. Updated documentation. [Stefan Eissing]
   
index 33c1535a8e9d265a79eeccf87058eb4dd3c809e4..afddf0da8dec3c903d1ad6f3a89b32aecb222f7e 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#
-#   standard stuff
-#
-
-
-LTLIBRARY_NAME    = libmd.la
-LTLIBRARY_SOURCES = \
+COMMON_SOURCES = \
        md_acme.c \
        md_acme_acct.c \
        md_acme_authz.c \
@@ -35,10 +29,9 @@ LTLIBRARY_SOURCES = \
        md_store.c \
        md_store_fs.c \
        md_util.c
-
-
-LTLIBRARY_DEPENDENCIES = md.h
-
+        
+COMMON_OBJECTS = $(COMMON_SOURCES:.c=.o)
+COMMON_SHOBJECTS = $(COMMON_SOURCES:.c=.slo)
 
 a2md_CFLAGS = $(EXTRA_INCLUDES)
 
@@ -48,8 +41,8 @@ a2md_OBJECTS = \
        md_cmd_reg.c \
        md_cmd_store.c
 
-a2md: $(a2md_OBJECTS) $(LTLIBRARY_NAME)
-       $(LINK) $(a2md_CFLAGS) $(a2md_LTFLAGS) $(a2md_OBJECTS) -lmd $(A2MD_LDADD) $(AP_LIBS)
+a2md: $(a2md_OBJECTS) $(COMMON_SHOBJECTS) md.h
+       $(LINK) $(a2md_CFLAGS) $(a2md_LTFLAGS) $(a2md_OBJECTS) $(COMMON_OBJECTS) $(A2MD_LDADD) $(AP_LIBS)
 
 # top be installed in bin dir
 bin_PROGRAMS = a2md
index e0e73f13a710e8e983dbc6ee8bbfcd6bc81f602d..1211f43ab2850396d8710d23dcf6c9c7240fe597 100644 (file)
@@ -242,19 +242,37 @@ AC_DEFUN([APACHE_CHECK_JANSSON],[
 dnl #  start of module specific part
 APACHE_MODPATH_INIT(md)
 
+dnl #  list of common object files
+md_common_objs="dnl
+md_acme.o dnl
+md_acme_acct.o dnl
+md_acme_authz.o dnl
+md_acme_drive.o dnl
+md_core.o dnl
+md_curl.o dnl
+md_crypt.o dnl
+md_http.o dnl
+md_json.o dnl
+md_jws.o dnl
+md_log.o dnl
+md_reg.o dnl
+md_store.o dnl
+md_store_fs.o dnl
+md_util.o dnl
+"
+
 dnl #  list of module object files
 md_objs="dnl
 mod_md.lo dnl
 mod_md_config.lo dnl
 mod_md_os.lo dnl
-libmd.la dnl
 "
 
 # Ensure that other modules can pick up mod_md.h
 APR_ADDTO(INCLUDES, [-I\$(top_srcdir)/$modpath_current])
 
 dnl # hook module into the Autoconf mechanism (--enable-md)
-APACHE_MODULE(md, [Managed Domain handling], $md_objs, , most, [
+APACHE_MODULE(md, [Managed Domain handling], $md_objs $md_common_objs, , most, [
     APACHE_CHECK_OPENSSL
     if test "x$ac_cv_openssl" = "xno" ; then
         AC_MSG_WARN([libssl (or compatible) not found])
@@ -272,8 +290,6 @@ APACHE_MODULE(md, [Managed Domain handling], $md_objs, , most, [
         AC_MSG_WARN([libcurl not found])
         enable_md=no
     fi
-    
-    APR_ADDTO(A2MD_LDADD, [ "libmd.la" ])
 ])
 
 dnl #  end of module specific part
index d4b5c8a57a94c441c100921d1af3ccf665cb1816..efde431eea0db2e12cec2cbb74ef7798160e54ab 100644 (file)
@@ -90,7 +90,8 @@ apr_status_t md_acme_init(apr_pool_t *p, const char *base)
     return md_crypt_init(p);
 }
 
-apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url)
+apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url,
+                            const char *proxy_url)
 {
     md_acme_t *acme;
     const char *err = NULL;
@@ -113,6 +114,7 @@ apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url)
     acme->p = p;
     acme->user_agent = apr_psprintf(p, "%s mod_md/%s", 
                                     base_product, MOD_MD_VERSION);
+    acme->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL;
     acme->max_retries = 3;
     
     if (APR_SUCCESS != (rv = apr_uri_parse(p, url, &uri_parsed))) {
@@ -134,7 +136,7 @@ apr_status_t md_acme_setup(md_acme_t *acme)
     
     assert(acme->url);
     if (!acme->http && APR_SUCCESS != (rv = md_http_create(&acme->http, acme->p,
-                                                           acme->user_agent))) {
+                                                           acme->user_agent, acme->proxy_url))) {
         return rv;
     }
     md_http_set_response_limit(acme->http, 1024*1024);
index 25af1da0589e60bebeb50846f5296ee299b82327..ec130a0755ba0a43d4e155d7fc547fe5f10d9e8e 100644 (file)
@@ -50,6 +50,7 @@ struct md_acme_t {
     const char *sname;              /* short name for the service, not necessarily unique */
     apr_pool_t *p;
     const char *user_agent;
+    const char *proxy_url;
     struct md_acme_acct_t *acct;
     struct md_pkey_t *acct_key;
     
@@ -77,8 +78,10 @@ apr_status_t md_acme_init(apr_pool_t *pool, const char *base_version);
  * @param pacme   will hold the ACME server instance on success
  * @param p       pool to used
  * @param url     url of the server, optional if known at path
+ * @param proxy_url optional url of a HTTP(S) proxy to use
  */
-apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url);
+apr_status_t md_acme_create(md_acme_t **pacme, apr_pool_t *p, const char *url,
+                            const char *proxy_url);
 
 /**
  * Contact the ACME server and retrieve its directory information.
index e07a3c06a325fa045ea61bdb48f3024c1c5fdbbd..8fbaa28b590a87290d7829afcd47320686af6881 100644 (file)
@@ -456,7 +456,7 @@ apr_status_t md_acme_authz_respond(md_acme_authz_t *authz, md_acme_t *acme, md_s
                                    md_pkey_spec_t *key_spec, apr_pool_t *p)
 {
     apr_status_t rv;
-    int i;
+    unsigned int i;
     cha_find_ctx fctx;
     
     assert(acme);
index bf31e4b6e92a61c4ff46cf53aab3004f6f4f8d58..e4b01b757a205c225a27f14a15390afd7a82034d 100644 (file)
@@ -75,7 +75,7 @@ static apr_status_t ad_set_acct(md_proto_driver_t *d)
     
     ad->phase = "setup acme";
     if (!ad->acme 
-        && APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, md->ca_url))) {
+        && APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, md->ca_url, d->proxy_url))) {
         goto out;
     }
 
@@ -701,7 +701,7 @@ static apr_status_t acme_stage(md_proto_driver_t *d)
     }
     
     if (renew) {
-        if (APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, d->md->ca_url)) 
+        if (APR_SUCCESS != (rv = md_acme_create(&ad->acme, d->p, d->md->ca_url, d->proxy_url)) 
             || APR_SUCCESS != (rv = md_acme_setup(ad->acme))) {
             md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, d->p, "%s: setup ACME(%s)", 
                           d->md->name, d->md->ca_url);
@@ -876,7 +876,7 @@ static apr_status_t acme_driver_stage(md_proto_driver_t *d)
 /* ACME preload */
 
 static apr_status_t acme_preload(md_store_t *store, md_store_group_t load_group, 
-                                 const char *name, apr_pool_t *p) 
+                                 const char *name, const char *proxy_url, apr_pool_t *p) 
 {
     apr_status_t rv;
     md_pkey_t *privkey, *acct_key;
@@ -932,7 +932,7 @@ static apr_status_t acme_preload(md_store_t *store, md_store_group_t load_group,
     if (acct) {
         md_acme_t *acme;
         
-        if (APR_SUCCESS != (rv = md_acme_create(&acme, p, md->ca_url))
+        if (APR_SUCCESS != (rv = md_acme_create(&acme, p, md->ca_url, proxy_url))
             || APR_SUCCESS != (rv = md_acme_acct_save(store, p, acme, acct, acct_key))) {
             md_log_perror(MD_LOG_MARK, MD_LOG_ERR, rv, p, "%s: error saving acct", name);
             return rv;
@@ -964,7 +964,7 @@ static apr_status_t acme_driver_preload(md_proto_driver_t *d, md_store_group_t g
     apr_status_t rv;
 
     ad->phase = "ACME preload";
-    if (APR_SUCCESS == (rv = acme_preload(d->store, group, d->md->name, d->p))) {
+    if (APR_SUCCESS == (rv = acme_preload(d->store, group, d->md->name, d->proxy_url, d->p))) {
         ad->phase = "preload done";
     }
         
index d2778bb4288710e21d47844aceca7e390f6483b5..bd7dcc2e682997780e128155eed51ddeaacf4223 100644 (file)
@@ -50,6 +50,8 @@ struct md_cmd_ctx {
     const char *const *argv;
 };
 
+#define MD_CMD_OPT_PROXY_URL        "proxy-url"
+
 int md_cmd_ctx_has_option(md_cmd_ctx *ctx, const char *key);
 const char *md_cmd_ctx_get_option(md_cmd_ctx *ctx, const char *key);
 
index 5cab34ec8342aa5a1e1bc7c9bfbd82be98bbca85..bff4e13ad377c27ae1b446daf6287bb24b9595e7 100644 (file)
@@ -174,7 +174,8 @@ static apr_status_t cmd_process(md_cmd_ctx *ctx, const md_cmd_t *cmd)
             fprintf(stderr, "need store for registry: %s\n", cmd->name);
             return APR_EINVAL;
         }
-        if (APR_SUCCESS != (rv = md_reg_init(&ctx->reg, ctx->p, ctx->store))) {
+        if (APR_SUCCESS != (rv = md_reg_init(&ctx->reg, ctx->p, ctx->store,
+                                             md_cmd_ctx_get_option(ctx, MD_CMD_OPT_PROXY_URL)))) {
             fprintf(stderr, "error %d creating registry from store: %s\n", rv, ctx->base_dir);
             return APR_EINVAL;
         }
@@ -184,7 +185,8 @@ static apr_status_t cmd_process(md_cmd_ctx *ctx, const md_cmd_t *cmd)
             fprintf(stderr, "need store for ACME: %s\n", cmd->name);
             return APR_EINVAL;
         }
-        rv = md_acme_create(&ctx->acme, ctx->p, ctx->ca_url);
+        rv = md_acme_create(&ctx->acme, ctx->p, ctx->ca_url, 
+                            md_cmd_ctx_get_option(ctx, MD_CMD_OPT_PROXY_URL));
         if (APR_SUCCESS != rv) {
             fprintf(stderr, "error creating acme instance %s (%s)\n", 
                     ctx->ca_url, ctx->base_dir);
@@ -326,6 +328,9 @@ static apr_status_t main_opts(md_cmd_ctx *ctx, int option, const char *optarg)
         case 'j':
             init_json_out(ctx);
             break;
+        case 'p':
+            md_cmd_ctx_set_option(ctx, MD_CMD_OPT_PROXY_URL, optarg);
+            break;
         case 'q':
             if (active_level > 0) {
                 --active_level;
@@ -363,6 +368,7 @@ static apr_getopt_option_t MainOptions [] = {
     { "dir",     'd', 1, "directory for file data"},
     { "help",    'h', 0, "print usage information"},
     { "json",    'j', 0, "produce json output"},
+    { "proxy",   'p', 1, "use the HTTP proxy url"},
     { "quiet",   'q', 0, "produce less output"},
     { "terms",   't', 1, "you agree to the terms of services (url)" },
     { "verbose", 'v', 0, "produce more output" },
index 5582ae6b9b445931d8ee1b2dd4515d11ea731d6c..a8646332658cc55e864cd6d6e480128ceff62bdc 100644 (file)
@@ -209,15 +209,16 @@ int md_should_renew(const md_t *md)
         return 1;
     }
     else if (md->expires > 0) {
-        apr_interval_time_t renew_win, left, life;
+        double renew_win,  life;
+        apr_interval_time_t left;
         
-        renew_win = md->renew_window;
+        renew_win = (double)md->renew_window;
         if (md->renew_norm > 0 
             && md->renew_norm > renew_win
             && md->expires > md->valid_from) {
             /* Calc renewal days as fraction of cert lifetime - if known */
-            life = md->expires - md->valid_from
-            renew_win = (apr_time_t)(life * ((double)renew_win / md->renew_norm));
+            life = (double)(md->expires - md->valid_from)
+            renew_win = life * renew_win / (double)md->renew_norm;
         }
         
         left = md->expires - now;
index f948efd8ec8706f014012bb387d50af19baec957..cb3b4d91f3838f3d35aa7715ef6208e342e31518 100644 (file)
@@ -219,6 +219,9 @@ static apr_status_t curl_perform(md_http_request_t *req)
     if (req->user_agent) {
         curl_easy_setopt(curl, CURLOPT_USERAGENT, req->user_agent);
     }
+    if (req->proxy_url) {
+        curl_easy_setopt(curl, CURLOPT_PROXY, req->proxy_url);
+    }
     if (!apr_is_empty_table(req->headers)) {
         curlify_hdrs_ctx ctx;
         
index 984066d9e1c9a47a5255a031fb58a46794d04e55..f1c88e8e283c97354ea4eba332b5226914016dec 100644 (file)
@@ -27,6 +27,7 @@ struct md_http_t {
     apr_off_t resp_limit;
     md_http_impl_t *impl;
     const char *user_agent;
+    const char *proxy_url;
 };
 
 static md_http_impl_t *cur_impl;
@@ -42,7 +43,8 @@ void md_http_use_implementation(md_http_impl_t *impl)
 
 static long next_req_id;
 
-apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_agent)
+apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_agent,
+                            const char *proxy_url)
 {
     md_http_t *http;
     apr_status_t rv = APR_SUCCESS;
@@ -65,6 +67,7 @@ apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_a
     http->pool = p;
     http->impl = cur_impl;
     http->user_agent = apr_pstrdup(p, user_agent);
+    http->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL;
     http->bucket_alloc = apr_bucket_alloc_create(p);
     if (!http->bucket_alloc) {
         return APR_EGENERAL;
@@ -103,6 +106,7 @@ static apr_status_t req_create(md_http_request_t **preq, md_http_t *http,
     req->cb = cb;
     req->baton = baton;
     req->user_agent = http->user_agent;
+    req->proxy_url = http->proxy_url;
 
     *preq = req;
     return rv;
index e6810b9da760d8065f16a637cfb47f0538f9efc7..874af4a2330848005e89edc0609bdc30d7da2c4e 100644 (file)
@@ -35,6 +35,7 @@ struct md_http_request_t {
     const char *method;
     const char *url;
     const char *user_agent;
+    const char *proxy_url;
     apr_table_t *headers;
     struct apr_bucket_brigade *body;
     apr_off_t body_len;
@@ -52,7 +53,8 @@ struct md_http_response_t {
     struct apr_bucket_brigade *body;
 };
 
-apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_agent);
+apr_status_t md_http_create(md_http_t **phttp, apr_pool_t *p, const char *user_agent,
+                            const char *proxy_url);
 
 void md_http_set_response_limit(md_http_t *http, apr_off_t resp_limit);
 
index 6a32508f97039b543b9fa44628c10df6bf6454f3..4d1e2171767930079ba40cb26ef65dd532952279 100644 (file)
@@ -40,12 +40,14 @@ struct md_reg_t {
     int was_synched;
     int can_http;
     int can_https;
+    const char *proxy_url;
 };
 
 /**************************************************************************************************/
 /* life cycle */
 
-apr_status_t md_reg_init(md_reg_t **preg, apr_pool_t *p, struct md_store_t *store)
+apr_status_t md_reg_init(md_reg_t **preg, apr_pool_t *p, struct md_store_t *store,
+                         const char *proxy_url)
 {
     md_reg_t *reg;
     apr_status_t rv;
@@ -55,7 +57,7 @@ apr_status_t md_reg_init(md_reg_t **preg, apr_pool_t *p, struct md_store_t *stor
     reg->protos = apr_hash_make(p);
     reg->can_http = 1;
     reg->can_https = 1;
-    
+    reg->proxy_url = proxy_url? apr_pstrdup(p, proxy_url) : NULL;
     rv = md_acme_protos_add(reg->protos, p);
     
     *preg = (rv == APR_SUCCESS)? reg : NULL;
@@ -821,6 +823,7 @@ static apr_status_t init_proto_driver(md_proto_driver_t *driver, const md_proto_
         driver->can_https = reg->can_https;
         driver->reg = reg;
         driver->store = md_reg_store_get(reg);
+        driver->proxy_url = reg->proxy_url;
         driver->md = md;
         driver->reset = reset;
     }
index d889b8abd02c0b16dc00bb0cb7533526e0f1f63a..9d5284c435be0314c4143cb59a632dd3077b2c2c 100644 (file)
@@ -32,7 +32,8 @@ typedef struct md_reg_t md_reg_t;
  * Initialize the registry, using the pool and loading any existing information
  * from the store.
  */
-apr_status_t md_reg_init(md_reg_t **preg, apr_pool_t *pm, struct md_store_t *store);
+apr_status_t md_reg_init(md_reg_t **preg, apr_pool_t *pm, struct md_store_t *store,
+                         const char *proxy_url);
 
 struct md_store_t *md_reg_store_get(md_reg_t *reg);
 
@@ -136,6 +137,7 @@ struct md_proto_driver_t {
     void *baton;
     int reset;
     apr_time_t stage_valid_from;
+    const char *proxy_url;
 };
 
 typedef apr_status_t md_proto_init_cb(md_proto_driver_t *driver);
index 8958a5d63759ed6c77e2faffe56a6447b94b15c8..756aaef382acbe57f207d3a07723d3819dd0f28a 100644 (file)
@@ -804,7 +804,7 @@ apr_size_t md_util_base64url_decode(const char **decoded, const char *encoded,
     while (*p && BASE64URL_UINT6[ *p ] != N6) {
         ++p;
     }
-    len = p - e;
+    len = (int)(p - e);
     mlen = (len/4)*4;
     *decoded = apr_pcalloc(pool, (apr_size_t)len + 1);
     
index 7c03dc75489f8908adbf265eaab1130851611e91..43576676d7dc1d1233e87b39aa68a8269e847234 100644 (file)
@@ -26,7 +26,7 @@
  * @macro
  * Version number of the md module as c string
  */
-#define MOD_MD_VERSION "0.9.1-git"
+#define MOD_MD_VERSION "0.9.2-git"
 
 /**
  * @macro
@@ -34,7 +34,7 @@
  * release. This is a 24 bit number with 8 bits for major number, 8 bits
  * for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
  */
-#define MOD_MD_VERSION_NUM 0x000901
+#define MOD_MD_VERSION_NUM 0x000902
 
 #define MD_EXPERIMENTAL 0
 #define MD_ACME_DEF_URL    "https://acme-v01.api.letsencrypt.org/directory"
index ac31aa98481e98e23c2700680110c933b5b9cded..74252881dbf8cf38c1732f21405e67c6473f6efb 100644 (file)
@@ -377,7 +377,7 @@ static apr_status_t setup_reg(md_reg_t **preg, apr_pool_t *p, server_rec *s, int
     mc = sc->mc;
     
     if (mc->store || APR_SUCCESS == (rv = setup_store(mc, p, s, post_config))) {
-        return md_reg_init(preg, p, mc->store);
+        return md_reg_init(preg, p, mc->store, mc->proxy_url);
     }
     return rv;
 }
@@ -870,7 +870,7 @@ static apr_status_t md_get_certificate(server_rec *s, apr_pool_t *p,
     if (sc && sc->assigned) {
         assert(sc->mc);
         assert(sc->mc->store);
-        if (APR_SUCCESS != (rv = md_reg_init(&reg, p, sc->mc->store))) {
+        if (APR_SUCCESS != (rv = md_reg_init(&reg, p, sc->mc->store, sc->mc->proxy_url))) {
             return rv;
         }
 
index 85e30d61e90bab2c3db81a751fc9b8f0f077a1e3..e309121367e1b2f0c15943db8ed09dd83237215c 100644 (file)
@@ -41,6 +41,7 @@
 #define MD_CMD_MEMBERS        "MDMembers"
 #define MD_CMD_PORTMAP        "MDPortMap"
 #define MD_CMD_PKEYS          "MDPrivateKeys"
+#define MD_CMD_PROXY          "MDHttpProxy"
 #define MD_CMD_RENEWWINDOW    "MDRenewWindow"
 #define MD_CMD_STOREDIR       "MDStoreDir"
 
@@ -51,6 +52,7 @@ static md_mod_conf_t defmc = {
     NULL,
     "md",
     NULL,
+    NULL,
     80,
     443,
     0,
@@ -442,6 +444,9 @@ static apr_status_t duration_parse(const char *value, apr_interval_time_t *ptime
             funits = MD_SECS_PER_DAY;
         }
     }
+    else if (endp == value) {
+        return APR_EINVAL;
+    }
     else if (*endp == 'd') {
         *ptimeout = apr_time_from_sec(n * MD_SECS_PER_DAY);
         return APR_SUCCESS;
@@ -506,6 +511,19 @@ static const char *md_config_set_renew_window(cmd_parms *cmd, void *dc, const ch
     return "MDRenewWindow has unrecognized format";
 }
 
+static const char *md_config_set_proxy(cmd_parms *cmd, void *arg, const char *value)
+{
+    md_srv_conf_t *sc = md_config_get(cmd->server);
+    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
+
+    if (err) {
+        return err;
+    }
+    sc->mc->proxy_url = value;
+    (void)arg;
+    return NULL;
+}
+
 static const char *md_config_set_store_dir(cmd_parms *cmd, void *arg, const char *value)
 {
     md_srv_conf_t *sc = md_config_get(cmd->server);
@@ -679,6 +697,8 @@ const command_rec md_cmds[] = {
                   "the outside."),
     AP_INIT_TAKE_ARGV( MD_CMD_PKEYS, md_config_set_pkeys, NULL, RSRC_CONF, 
                   "set the type and parameters for private key generation"),
+    AP_INIT_TAKE1(     MD_CMD_PROXY, md_config_set_proxy, NULL, RSRC_CONF, 
+                  "URL of a HTTP(S) proxy to use for outgoing connections"),
     AP_INIT_TAKE1(     MD_CMD_STOREDIR, md_config_set_store_dir, NULL, RSRC_CONF, 
                   "the directory for file system storage of managed domain data."),
     AP_INIT_TAKE1(     MD_CMD_RENEWWINDOW, md_config_set_renew_window, NULL, RSRC_CONF, 
@@ -725,6 +745,8 @@ const char *md_config_gets(const md_srv_conf_t *sc, md_config_var_t var)
             return sc->ca_proto? sc->ca_proto : defconf.ca_proto;
         case MD_CONFIG_BASE_DIR:
             return sc->mc->base_dir;
+        case MD_CONFIG_PROXY:
+            return sc->mc->proxy_url;
         case MD_CONFIG_CA_AGREEMENT:
             return sc->ca_agreement? sc->ca_agreement : defconf.ca_agreement;
         default:
index e5dc4aa6fc782fbd8ffe6377a6a403a054615d0c..b385509476cba1cae81dc31866dc3d258256a9c9 100644 (file)
@@ -30,11 +30,13 @@ typedef enum {
     MD_CONFIG_RENEW_NORM,
     MD_CONFIG_RENEW_WINDOW,
     MD_CONFIG_TRANSITIVE,
+    MD_CONFIG_PROXY,
 } md_config_var_t;
 
 typedef struct {
     apr_array_header_t *mds;           /* all md_t* defined in the config, shared */
     const char *base_dir;              /* base dir for store */
+    const char *proxy_url;             /* proxy url to use (or NULL) */
     struct md_store_t *store;          /* store instance, singleton, shared */
 
     int local_80;                      /* On which port http:80 arrives */