summaryrefslogtreecommitdiffstats
path: root/modules/md
diff options
context:
space:
mode:
authorStefan Eissing <icing@apache.org>2017-09-08 16:55:04 +0200
committerStefan Eissing <icing@apache.org>2017-09-08 16:55:04 +0200
commit05c77cadd7ae366cb1e6d09d9bf44c0939ae2c51 (patch)
tree005be5c4c462a1ef48960aa26c95d67c03fa63dc /modules/md
parentOn the trunk: (diff)
downloadapache2-05c77cadd7ae366cb1e6d09d9bf44c0939ae2c51.tar.xz
apache2-05c77cadd7ae366cb1e6d09d9bf44c0939ae2c51.zip
On the trunk:
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
Diffstat (limited to 'modules/md')
-rw-r--r--modules/md/Makefile.in19
-rw-r--r--modules/md/config2.m424
-rw-r--r--modules/md/md_acme.c6
-rw-r--r--modules/md/md_acme.h5
-rw-r--r--modules/md/md_acme_authz.c2
-rw-r--r--modules/md/md_acme_drive.c10
-rw-r--r--modules/md/md_cmd.h2
-rw-r--r--modules/md/md_cmd_main.c10
-rw-r--r--modules/md/md_core.c9
-rw-r--r--modules/md/md_curl.c3
-rw-r--r--modules/md/md_http.c6
-rw-r--r--modules/md/md_http.h4
-rw-r--r--modules/md/md_reg.c7
-rw-r--r--modules/md/md_reg.h4
-rw-r--r--modules/md/md_util.c2
-rw-r--r--modules/md/md_version.h4
-rw-r--r--modules/md/mod_md.c4
-rw-r--r--modules/md/mod_md_config.c22
-rw-r--r--modules/md/mod_md_config.h2
19 files changed, 103 insertions, 42 deletions
diff --git a/modules/md/Makefile.in b/modules/md/Makefile.in
index 33c1535a8e..afddf0da8d 100644
--- a/modules/md/Makefile.in
+++ b/modules/md/Makefile.in
@@ -13,13 +13,7 @@
# 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
diff --git a/modules/md/config2.m4 b/modules/md/config2.m4
index e0e73f13a7..1211f43ab2 100644
--- a/modules/md/config2.m4
+++ b/modules/md/config2.m4
@@ -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
diff --git a/modules/md/md_acme.c b/modules/md/md_acme.c
index d4b5c8a57a..efde431eea 100644
--- a/modules/md/md_acme.c
+++ b/modules/md/md_acme.c
@@ -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);
diff --git a/modules/md/md_acme.h b/modules/md/md_acme.h
index 25af1da058..ec130a0755 100644
--- a/modules/md/md_acme.h
+++ b/modules/md/md_acme.h
@@ -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.
diff --git a/modules/md/md_acme_authz.c b/modules/md/md_acme_authz.c
index e07a3c06a3..8fbaa28b59 100644
--- a/modules/md/md_acme_authz.c
+++ b/modules/md/md_acme_authz.c
@@ -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);
diff --git a/modules/md/md_acme_drive.c b/modules/md/md_acme_drive.c
index bf31e4b6e9..e4b01b757a 100644
--- a/modules/md/md_acme_drive.c
+++ b/modules/md/md_acme_drive.c
@@ -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";
}
diff --git a/modules/md/md_cmd.h b/modules/md/md_cmd.h
index d2778bb428..bd7dcc2e68 100644
--- a/modules/md/md_cmd.h
+++ b/modules/md/md_cmd.h
@@ -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);
diff --git a/modules/md/md_cmd_main.c b/modules/md/md_cmd_main.c
index 5cab34ec83..bff4e13ad3 100644
--- a/modules/md/md_cmd_main.c
+++ b/modules/md/md_cmd_main.c
@@ -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" },
diff --git a/modules/md/md_core.c b/modules/md/md_core.c
index 5582ae6b9b..a864633265 100644
--- a/modules/md/md_core.c
+++ b/modules/md/md_core.c
@@ -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;
diff --git a/modules/md/md_curl.c b/modules/md/md_curl.c
index f948efd8ec..cb3b4d91f3 100644
--- a/modules/md/md_curl.c
+++ b/modules/md/md_curl.c
@@ -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;
diff --git a/modules/md/md_http.c b/modules/md/md_http.c
index 984066d9e1..f1c88e8e28 100644
--- a/modules/md/md_http.c
+++ b/modules/md/md_http.c
@@ -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;
diff --git a/modules/md/md_http.h b/modules/md/md_http.h
index e6810b9da7..874af4a233 100644
--- a/modules/md/md_http.h
+++ b/modules/md/md_http.h
@@ -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);
diff --git a/modules/md/md_reg.c b/modules/md/md_reg.c
index 6a32508f97..4d1e217176 100644
--- a/modules/md/md_reg.c
+++ b/modules/md/md_reg.c
@@ -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;
}
diff --git a/modules/md/md_reg.h b/modules/md/md_reg.h
index d889b8abd0..9d5284c435 100644
--- a/modules/md/md_reg.h
+++ b/modules/md/md_reg.h
@@ -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);
diff --git a/modules/md/md_util.c b/modules/md/md_util.c
index 8958a5d637..756aaef382 100644
--- a/modules/md/md_util.c
+++ b/modules/md/md_util.c
@@ -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);
diff --git a/modules/md/md_version.h b/modules/md/md_version.h
index 7c03dc7548..43576676d7 100644
--- a/modules/md/md_version.h
+++ b/modules/md/md_version.h
@@ -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"
diff --git a/modules/md/mod_md.c b/modules/md/mod_md.c
index ac31aa9848..74252881db 100644
--- a/modules/md/mod_md.c
+++ b/modules/md/mod_md.c
@@ -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;
}
diff --git a/modules/md/mod_md_config.c b/modules/md/mod_md_config.c
index 85e30d61e9..e309121367 100644
--- a/modules/md/mod_md_config.c
+++ b/modules/md/mod_md_config.c
@@ -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:
diff --git a/modules/md/mod_md_config.h b/modules/md/mod_md_config.h
index e5dc4aa6fc..b385509476 100644
--- a/modules/md/mod_md_config.h
+++ b/modules/md/mod_md_config.h
@@ -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 */