You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2019/06/24 16:04:33 UTC
svn commit: r1862013 [6/8] - in /httpd/httpd/trunk: ./ modules/md/
Modified: httpd/httpd/trunk/modules/md/md_store_fs.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_store_fs.c?rev=1862013&r1=1862012&r2=1862013&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_store_fs.c (original)
+++ httpd/httpd/trunk/modules/md/md_store_fs.c Mon Jun 24 16:04:32 2019
@@ -84,6 +84,8 @@ static apr_status_t fs_move(md_store_t *
static apr_status_t fs_iterate(md_store_inspect *inspect, void *baton, md_store_t *store,
apr_pool_t *p, md_store_group_t group, const char *pattern,
const char *aspect, md_store_vtype_t vtype);
+static apr_status_t fs_iterate_names(md_store_inspect *inspect, void *baton, md_store_t *store,
+ apr_pool_t *p, md_store_group_t group, const char *pattern);
static apr_status_t fs_get_fname(const char **pfname,
md_store_t *store, md_store_group_t group,
@@ -122,13 +124,12 @@ static apr_status_t rename_pkey(void *ba
{
const char *from, *to;
apr_status_t rv = APR_SUCCESS;
- MD_CHK_VARS;
(void)baton;
(void)ftype;
if ( MD_OK(md_util_path_merge(&from, ptemp, dir, name, NULL))
&& MD_OK(md_util_path_merge(&to, ptemp, dir, MD_FN_PRIVKEY, NULL))) {
- md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, p, "renaming %s/%s to %s",
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, p, "renaming %s/%s to %s",
dir, name, MD_FN_PRIVKEY);
return apr_file_rename(from, to, ptemp);
}
@@ -143,16 +144,15 @@ static apr_status_t mk_pubcert(void *bat
apr_array_header_t *chain, *pubcert;
const char *fname, *fpubcert;
apr_status_t rv = APR_SUCCESS;
- MD_CHK_VARS;
(void)baton;
(void)ftype;
(void)p;
if ( MD_OK(md_util_path_merge(&fpubcert, ptemp, dir, MD_FN_PUBCERT, NULL))
- && MD_IS_ERR(md_chain_fload(&pubcert, ptemp, fpubcert), ENOENT)
+ && APR_STATUS_IS_ENOENT(rv = md_chain_fload(&pubcert, ptemp, fpubcert))
&& MD_OK(md_util_path_merge(&fname, ptemp, dir, name, NULL))
&& MD_OK(md_cert_fload(&cert, ptemp, fname))
- && MD_OK(md_util_path_merge(&fname, ptemp, dir, MD_FN_CHAIN, NULL))) {
+ && MD_OK(md_util_path_merge(&fname, ptemp, dir, "chain.pem", NULL))) {
rv = md_chain_fload(&chain, ptemp, fname);
if (APR_STATUS_IS_ENOENT(rv)) {
@@ -196,7 +196,6 @@ static apr_status_t read_store_file(md_s
const char *key64, *key;
apr_status_t rv;
double store_version;
- MD_CHK_VARS;
if (MD_OK(md_json_readf(&json, p, fname))) {
store_version = md_json_getn(json, MD_KEY_STORE, MD_KEY_VERSION, NULL);
@@ -249,7 +248,6 @@ static apr_status_t setup_store_file(voi
md_store_fs_t *s_fs = baton;
const char *fname;
apr_status_t rv;
- MD_CHK_VARS;
(void)ap;
s_fs->plain_pkey[MD_SG_DOMAINS] = 1;
@@ -264,7 +262,7 @@ read:
rv = read_store_file(s_fs, fname, p, ptemp);
}
else if (APR_STATUS_IS_ENOENT(rv)
- && MD_IS_ERR(init_store_file(s_fs, fname, p, ptemp), EEXIST)) {
+ && APR_STATUS_IS_EEXIST(rv = init_store_file(s_fs, fname, p, ptemp))) {
goto read;
}
return rv;
@@ -274,7 +272,6 @@ apr_status_t md_store_fs_init(md_store_t
{
md_store_fs_t *s_fs;
apr_status_t rv = APR_SUCCESS;
- MD_CHK_VARS;
s_fs = apr_pcalloc(p, sizeof(*s_fs));
@@ -284,6 +281,7 @@ apr_status_t md_store_fs_init(md_store_t
s_fs->s.move = fs_move;
s_fs->s.purge = fs_purge;
s_fs->s.iterate = fs_iterate;
+ s_fs->s.iterate_names = fs_iterate_names;
s_fs->s.get_fname = fs_get_fname;
s_fs->s.is_newer = fs_is_newer;
@@ -303,7 +301,7 @@ apr_status_t md_store_fs_init(md_store_t
s_fs->base = apr_pstrdup(p, path);
- if (MD_IS_ERR(md_util_is_dir(s_fs->base, p), ENOENT)
+ if (APR_STATUS_IS_ENOENT(rv = md_util_is_dir(s_fs->base, p))
&& MD_OK(apr_dir_make_recursive(s_fs->base, s_fs->def_perms.dir, p))) {
rv = apr_file_perms_set(s_fs->base, MD_FPROT_D_UALL_WREAD);
if (APR_STATUS_IS_ENOTIMPL(rv)) {
@@ -446,7 +444,6 @@ static apr_status_t pfs_load(void *baton
md_store_group_t group;
void **pvalue;
apr_status_t rv;
- MD_CHK_VARS;
group = (md_store_group_t)va_arg(ap, int);
name = va_arg(ap, const char *);
@@ -477,7 +474,6 @@ static apr_status_t mk_group_dir(const c
{
const perms_t *perms;
apr_status_t rv;
- MD_CHK_VARS;
perms = gperms(s_fs, group);
@@ -507,7 +503,6 @@ static apr_status_t pfs_is_newer(void *b
apr_finfo_t inf1, inf2;
int *pnewer;
apr_status_t rv;
- MD_CHK_VARS;
(void)p;
group1 = (md_store_group_t)va_arg(ap, int);
@@ -554,7 +549,6 @@ static apr_status_t pfs_save(void *baton
const perms_t *perms;
const char *pass;
apr_size_t pass_len;
- MD_CHK_VARS;
group = (md_store_group_t)va_arg(ap, int);
name = va_arg(ap, const char*);
@@ -612,7 +606,6 @@ static apr_status_t pfs_remove(void *bat
int force;
apr_finfo_t info;
md_store_group_t group;
- MD_CHK_VARS;
(void)p;
group = (md_store_group_t)va_arg(ap, int);
@@ -624,7 +617,7 @@ static apr_status_t pfs_remove(void *bat
if ( MD_OK(md_util_path_merge(&dir, ptemp, s_fs->base, groupname, name, NULL))
&& MD_OK(md_util_path_merge(&fpath, ptemp, dir, aspect, NULL))) {
- md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, 0, ptemp, "start remove of md %s/%s/%s",
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, 0, ptemp, "start remove of md %s/%s/%s",
groupname, name, aspect);
if (!MD_OK(apr_stat(&info, dir, APR_FINFO_TYPE, ptemp))) {
@@ -673,7 +666,6 @@ static apr_status_t pfs_purge(void *bato
const char *dir, *name, *groupname;
md_store_group_t group;
apr_status_t rv;
- MD_CHK_VARS;
(void)p;
group = (md_store_group_t)va_arg(ap, int);
@@ -685,7 +677,7 @@ static apr_status_t pfs_purge(void *bato
/* Remove all files in dir, there should be no sub-dirs */
rv = md_util_rm_recursive(dir, ptemp, 1);
}
- md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "purge %s/%s (%s)", groupname, name, dir);
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE2, rv, ptemp, "purge %s/%s (%s)", groupname, name, dir);
return APR_SUCCESS;
}
@@ -706,6 +698,7 @@ typedef struct {
const char *aspect;
md_store_vtype_t vtype;
md_store_inspect *inspect;
+ const char *dirname;
void *baton;
} inspect_ctx;
@@ -716,15 +709,38 @@ static apr_status_t insp(void *baton, ap
apr_status_t rv;
void *value;
const char *fpath;
- MD_CHK_VARS;
(void)ftype;
md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting value at: %s/%s", dir, name);
- if ( MD_OK(md_util_path_merge(&fpath, ptemp, dir, name, NULL))
- && MD_OK(fs_fload(&value, ctx->s_fs, fpath, ctx->group, ctx->vtype, p, ptemp))
- && !ctx->inspect(ctx->baton, name, ctx->aspect, ctx->vtype, value, ptemp)) {
- return APR_EOF;
- }
+ if (APR_SUCCESS == (rv = md_util_path_merge(&fpath, ptemp, dir, name, NULL))) {
+ rv = fs_fload(&value, ctx->s_fs, fpath, ctx->group, ctx->vtype, p, ptemp);
+ if (APR_SUCCESS == rv
+ && !ctx->inspect(ctx->baton, ctx->dirname, name, ctx->vtype, value, p)) {
+ return APR_EOF;
+ }
+ else if (APR_STATUS_IS_ENOENT(rv)) {
+ rv = APR_SUCCESS;
+ }
+ }
+ return rv;
+}
+
+static apr_status_t insp_dir(void *baton, apr_pool_t *p, apr_pool_t *ptemp,
+ const char *dir, const char *name, apr_filetype_e ftype)
+{
+ inspect_ctx *ctx = baton;
+ apr_status_t rv;
+ const char *fpath;
+
+ (void)ftype;
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting dir at: %s/%s", dir, name);
+ if (MD_OK(md_util_path_merge(&fpath, p, dir, name, NULL))) {
+ ctx->dirname = name;
+ rv = md_util_files_do(insp, ctx, p, fpath, ctx->aspect, NULL);
+ if (APR_STATUS_IS_ENOENT(rv)) {
+ rv = APR_SUCCESS;
+ }
+ }
return rv;
}
@@ -745,7 +761,37 @@ static apr_status_t fs_iterate(md_store_
ctx.baton = baton;
groupname = md_store_group_name(group);
- rv = md_util_files_do(insp, &ctx, p, ctx.s_fs->base, groupname, ctx.pattern, aspect, NULL);
+ rv = md_util_files_do(insp_dir, &ctx, p, ctx.s_fs->base, groupname, pattern, NULL);
+
+ return rv;
+}
+
+static apr_status_t insp_name(void *baton, apr_pool_t *p, apr_pool_t *ptemp,
+ const char *dir, const char *name, apr_filetype_e ftype)
+{
+ inspect_ctx *ctx = baton;
+
+ (void)ftype;
+ (void)p;
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting name at: %s/%s", dir, name);
+ return ctx->inspect(ctx->baton, dir, name, 0, NULL, ptemp);
+}
+
+static apr_status_t fs_iterate_names(md_store_inspect *inspect, void *baton, md_store_t *store,
+ apr_pool_t *p, md_store_group_t group, const char *pattern)
+{
+ const char *groupname;
+ apr_status_t rv;
+ inspect_ctx ctx;
+
+ ctx.s_fs = FS_STORE(store);
+ ctx.group = group;
+ ctx.pattern = pattern;
+ ctx.inspect = inspect;
+ ctx.baton = baton;
+ groupname = md_store_group_name(group);
+
+ rv = md_util_files_do(insp_name, &ctx, p, ctx.s_fs->base, groupname, pattern, NULL);
return rv;
}
@@ -760,7 +806,6 @@ static apr_status_t pfs_move(void *baton
md_store_group_t from, to;
int archive;
apr_status_t rv;
- MD_CHK_VARS;
(void)p;
from = (md_store_group_t)va_arg(ap, int);
@@ -802,7 +847,7 @@ static apr_status_t pfs_move(void *baton
narch_dir = apr_psprintf(ptemp, "%s.%d", arch_dir, n);
rv = md_util_is_dir(narch_dir, ptemp);
if (APR_STATUS_IS_ENOENT(rv)) {
- md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "using archive dir: %s",
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, ptemp, "using archive dir: %s",
narch_dir);
break;
}
@@ -817,7 +862,7 @@ static apr_status_t pfs_move(void *baton
while (n < 1000) {
narch_dir = apr_psprintf(ptemp, "%s.%d", arch_dir, n);
if (MD_OK(apr_dir_make(narch_dir, MD_FPROT_D_UONLY, ptemp))) {
- md_log_perror(MD_LOG_MARK, MD_LOG_DEBUG, rv, ptemp, "using archive dir: %s",
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE1, rv, ptemp, "using archive dir: %s",
narch_dir);
break;
}
Added: httpd/httpd/trunk/modules/md/md_time.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_time.c?rev=1862013&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/md/md_time.c (added)
+++ httpd/httpd/trunk/modules/md/md_time.c Mon Jun 24 16:04:32 2019
@@ -0,0 +1,284 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdio.h>
+
+#include <apr_lib.h>
+#include <apr_strings.h>
+#include <apr_time.h>
+
+#include "md.h"
+#include "md_time.h"
+
+apr_time_t md_timeperiod_length(const md_timeperiod_t *period)
+{
+ return (period->start < period->end)? (period->end - period->start) : 0;
+}
+
+int md_timeperiod_contains(const md_timeperiod_t *period, apr_time_t time)
+{
+ return md_timeperiod_has_started(period, time)
+ && !md_timeperiod_has_ended(period, time);
+}
+
+int md_timeperiod_has_started(const md_timeperiod_t *period, apr_time_t time)
+{
+ return (time >= period->start);
+}
+
+int md_timeperiod_has_ended(const md_timeperiod_t *period, apr_time_t time)
+{
+ return (time >= period->start) && (time <= period->end);
+}
+
+char *md_timeperiod_print(apr_pool_t *p, const md_timeperiod_t *period)
+{
+ char tstart[APR_RFC822_DATE_LEN];
+ char tend[APR_RFC822_DATE_LEN];
+
+ apr_rfc822_date(tstart, period->start);
+ apr_rfc822_date(tend, period->end);
+ return apr_pstrcat(p, tstart, " - ", tend, NULL);
+}
+
+const char *md_duration_print(apr_pool_t *p, apr_interval_time_t duration)
+{
+ const char *s = "", *sep = "";
+ long days = (long)(apr_time_sec(duration) / MD_SECS_PER_DAY);
+ int rem = (int)(apr_time_sec(duration) % MD_SECS_PER_DAY);
+
+ if (days > 0) {
+ s = apr_psprintf(p, "%ld days", days);
+ sep = " ";
+ }
+ if (rem > 0) {
+ int hours = (rem / MD_SECS_PER_HOUR);
+ rem = (rem % MD_SECS_PER_HOUR);
+ if (hours > 0) {
+ s = apr_psprintf(p, "%s%s%02d hours", s, sep, hours);
+ sep = " ";
+ }
+ if (rem > 0) {
+ int minutes = (rem / 60);
+ rem = (rem % 60);
+ if (minutes > 0) {
+ s = apr_psprintf(p, "%s%s%02d minutes", s, sep, minutes);
+ }
+ if (rem > 0) {
+ s = apr_psprintf(p, "%s%s%02d seconds", s, sep, rem);
+ }
+ }
+ }
+ else if (days == 0) {
+ s = "0 seconds";
+ if (duration != 0) {
+ s = apr_psprintf(p, "%d ms", (int)apr_time_msec(duration));
+ }
+ }
+ return s;
+}
+
+static const char *duration_format(apr_pool_t *p, apr_interval_time_t duration)
+{
+ const char *s = "0";
+ int units = (int)(apr_time_sec(duration) / MD_SECS_PER_DAY);
+ int rem = (int)(apr_time_sec(duration) % MD_SECS_PER_DAY);
+
+ if (rem == 0) {
+ s = apr_psprintf(p, "%dd", units);
+ }
+ else {
+ units = (int)(apr_time_sec(duration) / MD_SECS_PER_HOUR);
+ rem = (int)(apr_time_sec(duration) % MD_SECS_PER_HOUR);
+ if (rem == 0) {
+ s = apr_psprintf(p, "%dh", units);
+ }
+ else {
+ units = (int)(apr_time_sec(duration) / 60);
+ rem = (int)(apr_time_sec(duration) % 60);
+ if (rem == 0) {
+ s = apr_psprintf(p, "%dmi", units);
+ }
+ else {
+ units = (int)(apr_time_sec(duration));
+ rem = (int)(apr_time_msec(duration) % 1000);
+ if (rem == 0) {
+ s = apr_psprintf(p, "%ds", units);
+ }
+ else {
+ s = apr_psprintf(p, "%dms", (int)(apr_time_msec(duration)));
+ }
+ }
+ }
+ }
+ return s;
+}
+
+apr_status_t md_duration_parse(apr_interval_time_t *ptimeout, const char *value,
+ const char *def_unit)
+{
+ char *endp;
+ apr_int64_t n;
+
+ n = apr_strtoi64(value, &endp, 10);
+ if (errno) {
+ return errno;
+ }
+ if (!endp || !*endp) {
+ if (!def_unit) def_unit = "s";
+ }
+ else if (endp == value) {
+ return APR_EINVAL;
+ }
+ else {
+ def_unit = endp;
+ }
+
+ switch (*def_unit) {
+ case 'D':
+ case 'd':
+ *ptimeout = apr_time_from_sec(n * MD_SECS_PER_DAY);
+ break;
+ case 's':
+ case 'S':
+ *ptimeout = (apr_interval_time_t) apr_time_from_sec(n);
+ break;
+ case 'h':
+ case 'H':
+ /* Time is in hours */
+ *ptimeout = (apr_interval_time_t) apr_time_from_sec(n * MD_SECS_PER_HOUR);
+ break;
+ case 'm':
+ case 'M':
+ switch (*(++def_unit)) {
+ /* Time is in milliseconds */
+ case 's':
+ case 'S':
+ *ptimeout = (apr_interval_time_t) n * 1000;
+ break;
+ /* Time is in minutes */
+ case 'i':
+ case 'I':
+ *ptimeout = (apr_interval_time_t) apr_time_from_sec(n * 60);
+ break;
+ default:
+ return APR_EGENERAL;
+ }
+ break;
+ default:
+ return APR_EGENERAL;
+ }
+ return APR_SUCCESS;
+}
+
+static apr_status_t percentage_parse(const char *value, int *ppercent)
+{
+ char *endp;
+ apr_int64_t n;
+
+ n = apr_strtoi64(value, &endp, 10);
+ if (errno) {
+ return errno;
+ }
+ if (*endp == '%') {
+ if (n < 0) {
+ return APR_BADARG;
+ }
+ *ppercent = (int)n;
+ return APR_SUCCESS;
+ }
+ return APR_EINVAL;
+}
+
+apr_status_t md_timeslice_create(const md_timeslice_t **pts, apr_pool_t *p,
+ apr_interval_time_t norm, apr_interval_time_t len)
+{
+ md_timeslice_t *ts;
+
+ ts = apr_pcalloc(p, sizeof(*ts));
+ ts->norm = norm;
+ ts->len = len;
+ *pts = ts;
+ return APR_SUCCESS;
+}
+
+const char *md_timeslice_parse(const md_timeslice_t **pts, apr_pool_t *p,
+ const char *val, apr_interval_time_t norm)
+{
+ md_timeslice_t *ts;
+ int percent;
+
+ *pts = NULL;
+ if (!val) {
+ return "cannot parse NULL value";
+ }
+
+ ts = apr_pcalloc(p, sizeof(*ts));
+ if (md_duration_parse(&ts->len, val, "d") == APR_SUCCESS) {
+ *pts = ts;
+ return NULL;
+ }
+ else {
+ switch (percentage_parse(val, &percent)) {
+ case APR_SUCCESS:
+ ts->norm = norm;
+ ts->len = apr_time_from_sec((apr_time_sec(norm) * percent / 100L));
+ *pts = ts;
+ return NULL;
+ case APR_BADARG:
+ return "percent must be less than 100";
+ }
+ }
+ return "has unrecognized format";
+}
+
+const char *md_timeslice_format(const md_timeslice_t *ts, apr_pool_t *p) {
+ if (ts->norm > 0) {
+ int percent = (int)(((long)apr_time_sec(ts->len)) * 100L
+ / ((long)apr_time_sec(ts->norm)));
+ return apr_psprintf(p, "%d%%", percent);
+ }
+ return duration_format(p, ts->len);
+}
+
+md_timeperiod_t md_timeperiod_slice_before_end(const md_timeperiod_t *period,
+ const md_timeslice_t *ts)
+{
+ md_timeperiod_t r;
+ apr_time_t duration = ts->len;
+
+ if (ts->norm > 0) {
+ int percent = (int)(((long)apr_time_sec(ts->len)) * 100L
+ / ((long)apr_time_sec(ts->norm)));
+ apr_time_t plen = md_timeperiod_length(period);
+ if (apr_time_sec(plen) > 100) {
+ duration = apr_time_from_sec(apr_time_sec(plen) * percent / 100);
+ }
+ else {
+ duration = plen * percent / 100;
+ }
+ }
+ r.start = period->end - duration;
+ r.end = period->end;
+ return r;
+}
+
+int md_timeslice_eq(const md_timeslice_t *ts1, const md_timeslice_t *ts2)
+{
+ if (ts1 == ts2) return 1;
+ if (!ts1 || !ts2) return 0;
+ return (ts1->norm == ts2->norm) && (ts1->len == ts2->len);
+}
Added: httpd/httpd/trunk/modules/md/md_time.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_time.h?rev=1862013&view=auto
==============================================================================
--- httpd/httpd/trunk/modules/md/md_time.h (added)
+++ httpd/httpd/trunk/modules/md/md_time.h Mon Jun 24 16:04:32 2019
@@ -0,0 +1,67 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef mod_md_md_time_h
+#define mod_md_md_time_h
+
+#include <stdio.h>
+
+#define MD_SECS_PER_HOUR (60*60)
+#define MD_SECS_PER_DAY (24*MD_SECS_PER_HOUR)
+
+typedef struct {
+ apr_time_t start;
+ apr_time_t end;
+} md_timeperiod_t;
+
+apr_time_t md_timeperiod_length(const md_timeperiod_t *period);
+
+int md_timeperiod_contains(const md_timeperiod_t *period, apr_time_t time);
+int md_timeperiod_has_started(const md_timeperiod_t *period, apr_time_t time);
+int md_timeperiod_has_ended(const md_timeperiod_t *period, apr_time_t time);
+
+char *md_timeperiod_print(apr_pool_t *p, const md_timeperiod_t *period);
+
+/**
+ * Print a human readable form of the give duration in days/hours/min/sec
+ */
+const char *md_duration_print(apr_pool_t *p, apr_interval_time_t duration);
+
+/**
+ * Parse a machine readable string duration in the form of NN[unit], where
+ * unit is d/h/mi/s/ms with the default given should the unit not be specified.
+ */
+apr_status_t md_duration_parse(apr_interval_time_t *ptimeout, const char *value,
+ const char *def_unit);
+
+typedef struct {
+ apr_interval_time_t norm; /* if > 0, normalized base length */
+ apr_interval_time_t len; /* length of the timespan */
+} md_timeslice_t;
+
+apr_status_t md_timeslice_create(const md_timeslice_t **pts, apr_pool_t *p,
+ apr_interval_time_t norm, apr_interval_time_t len);
+
+int md_timeslice_eq(const md_timeslice_t *ts1, const md_timeslice_t *ts2);
+
+const char *md_timeslice_parse(const md_timeslice_t **pts, apr_pool_t *p,
+ const char *val, apr_interval_time_t defnorm);
+const char *md_timeslice_format(const md_timeslice_t *ts, apr_pool_t *p);
+
+md_timeperiod_t md_timeperiod_slice_before_end(const md_timeperiod_t *period,
+ const md_timeslice_t *ts);
+
+#endif /* md_util_h */
Modified: httpd/httpd/trunk/modules/md/md_util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_util.c?rev=1862013&r1=1862012&r2=1862013&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_util.c (original)
+++ httpd/httpd/trunk/modules/md/md_util.c Mon Jun 24 16:04:32 2019
@@ -24,6 +24,7 @@
#include <apr_tables.h>
#include <apr_uri.h>
+#include "md.h"
#include "md_log.h"
#include "md_util.h"
@@ -67,8 +68,67 @@ apr_status_t md_util_pool_vdo(md_util_va
}
/**************************************************************************************************/
+/* data chunks */
+
+md_data *md_data_create(apr_pool_t *p, const char *data, apr_size_t len)
+{
+ md_data *d;
+
+ d = apr_palloc(p, sizeof(*d));
+ d->len = len;
+ d->data = len? apr_pstrndup(p, data, len) : NULL;
+ return d;
+}
+
+static const char * const hex_const[] = {
+ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0a", "0b", "0c", "0d", "0e", "0f",
+ "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "1a", "1b", "1c", "1d", "1e", "1f",
+ "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "2a", "2b", "2c", "2d", "2e", "2f",
+ "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "3a", "3b", "3c", "3d", "3e", "3f",
+ "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "4a", "4b", "4c", "4d", "4e", "4f",
+ "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "5a", "5b", "5c", "5d", "5e", "5f",
+ "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "6a", "6b", "6c", "6d", "6e", "6f",
+ "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "7a", "7b", "7c", "7d", "7e", "7f",
+ "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "8a", "8b", "8c", "8d", "8e", "8f",
+ "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "9a", "9b", "9c", "9d", "9e", "9f",
+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9", "aa", "ab", "ac", "ad", "ae", "af",
+ "b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", "ba", "bb", "bc", "bd", "be", "bf",
+ "c0", "c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "ca", "cb", "cc", "cd", "ce", "cf",
+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "da", "db", "dc", "dd", "de", "df",
+ "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "ea", "eb", "ec", "ed", "ee", "ef",
+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "fa", "fb", "fc", "fd", "fe", "ff",
+};
+
+apr_status_t md_data_to_hex(const char **phex, char separator,
+ apr_pool_t *p, const md_data *data)
+{
+ char *hex, *cp;
+ const char * x;
+ unsigned int i;
+
+ cp = hex = apr_pcalloc(p, ((separator? 3 : 2) * data->len) + 1);
+ if (!hex) {
+ *phex = NULL;
+ return APR_ENOMEM;
+ }
+ for (i = 0; i < data->len; ++i) {
+ x = hex_const[(unsigned char)data->data[i]];
+ if (i && separator) *cp++ = separator;
+ *cp++ = x[0];
+ *cp++ = x[1];
+ }
+ *phex = hex;
+ return APR_SUCCESS;
+}
+
+/**************************************************************************************************/
/* string related */
+int md_array_is_empty(const struct apr_array_header_t *array)
+{
+ return (array == NULL) || (array->nelts == 0);
+}
+
char *md_util_str_tolower(char *s)
{
char *orig = s;
@@ -230,6 +290,11 @@ apr_status_t md_util_is_file(const char
return rv;
}
+int md_file_exists(const char *fname, apr_pool_t *p)
+{
+ return (fname && *fname && APR_SUCCESS == md_util_is_file(fname, p));
+}
+
apr_status_t md_util_path_merge(const char **ppath, apr_pool_t *p, ...)
{
const char *segment, *path;
@@ -324,6 +389,13 @@ apr_status_t md_text_fcreatex(const char
if (APR_SUCCESS == rv) {
rv = write_text((void*)text, f, p);
apr_file_close(f);
+ /* See <https://github.com/icing/mod_md/issues/117>: when a umask
+ * is set, files need to be assigned permissions explicitly.
+ * Otherwise, as in the issues reported, it will break our access model. */
+ rv = apr_file_perms_set(fpath, perms);
+ if (APR_STATUS_IS_ENOTIMPL(rv)) {
+ rv = APR_SUCCESS;
+ }
}
return rv;
}
@@ -413,17 +485,25 @@ static apr_status_t match_and_do(md_util
}
pattern = APR_ARRAY_IDX(ctx->patterns, depth, const char *);
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
+ "path=%s depth=%d pattern=%s", path, depth, pattern);
rv = apr_dir_open(&d, path, ptemp);
if (APR_SUCCESS != rv) {
return rv;
}
while (APR_SUCCESS == (rv = apr_dir_read(&finfo, wanted, d))) {
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
+ "candidate=%s", finfo.name);
if (!strcmp(".", finfo.name) || !strcmp("..", finfo.name)) {
continue;
}
if (APR_SUCCESS == apr_fnmatch(pattern, finfo.name, 0)) {
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
+ "candidate=%s matches pattern", finfo.name);
if (ndepth < ctx->patterns->nelts) {
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
+ "need to go deepter");
if (APR_DIR == finfo.filetype) {
/* deeper and deeper, irgendwo in der tiefe leuchtet ein licht */
rv = md_util_path_merge(&npath, ptemp, path, finfo.name, NULL);
@@ -433,6 +513,8 @@ static apr_status_t match_and_do(md_util
}
}
else {
+ md_log_perror(MD_LOG_MARK, MD_LOG_TRACE4, 0, ptemp, "match_and_do "
+ "invoking inspector on name=%s", finfo.name);
rv = ctx->cb(ctx->baton, p, ptemp, path, finfo.name, finfo.filetype);
}
}
@@ -608,7 +690,7 @@ apr_status_t md_util_ftree_remove(const
/* DNS name checks ********************************************************************************/
-int md_util_is_dns_name(apr_pool_t *p, const char *hostname, int need_fqdn)
+int md_dns_is_name(apr_pool_t *p, const char *hostname, int need_fqdn)
{
char c, last = 0;
const char *cp = hostname;
@@ -649,6 +731,73 @@ int md_util_is_dns_name(apr_pool_t *p, c
return 1; /* empty string not allowed */
}
+int md_dns_is_wildcard(apr_pool_t *p, const char *domain)
+{
+ if (domain[0] != '*' || domain[1] != '.') return 0;
+ return md_dns_is_name(p, domain+2, 1);
+}
+
+int md_dns_matches(const char *pattern, const char *domain)
+{
+ const char *s;
+
+ if (!apr_strnatcasecmp(pattern, domain)) return 1;
+ if (pattern[0] == '*' && pattern[1] == '.') {
+ s = strchr(domain, '.');
+ if (s && !apr_strnatcasecmp(pattern+1, s)) return 1;
+ }
+ return 0;
+}
+
+apr_array_header_t *md_dns_make_minimal(apr_pool_t *p, apr_array_header_t *domains)
+{
+ apr_array_header_t *minimal;
+ const char *domain, *pattern;
+ int i, j, duplicate;
+
+ minimal = apr_array_make(p, domains->nelts, sizeof(const char *));
+ for (i = 0; i < domains->nelts; ++i) {
+ domain = APR_ARRAY_IDX(domains, i, const char*);
+ duplicate = 0;
+ /* is it matched in minimal already? */
+ for (j = 0; j < minimal->nelts; ++j) {
+ pattern = APR_ARRAY_IDX(minimal, j, const char*);
+ if (md_dns_matches(pattern, domain)) {
+ duplicate = 1;
+ break;
+ }
+ }
+ if (!duplicate) {
+ if (!md_dns_is_wildcard(p, domain)) {
+ /* plain name, will we see a wildcard that replaces it? */
+ for (j = i+1; j < domains->nelts; ++j) {
+ pattern = APR_ARRAY_IDX(domains, j, const char*);
+ if (md_dns_is_wildcard(p, pattern) && md_dns_matches(pattern, domain)) {
+ duplicate = 1;
+ break;
+ }
+ }
+ }
+ if (!duplicate) {
+ APR_ARRAY_PUSH(minimal, const char *) = domain;
+ }
+ }
+ }
+ return minimal;
+}
+
+int md_dns_domains_match(const apr_array_header_t *domains, const char *name)
+{
+ const char *domain;
+ int i;
+
+ for (i = 0; i < domains->nelts; ++i) {
+ domain = APR_ARRAY_IDX(domains, i, const char*);
+ if (md_dns_matches(domain, name)) return 1;
+ }
+ return 0;
+}
+
const char *md_util_schemify(apr_pool_t *p, const char *s, const char *def_scheme)
{
const char *cp = s;
@@ -682,7 +831,7 @@ static apr_status_t uri_check(apr_uri_t
if (!uri_parsed->hostname) {
err = "missing hostname";
}
- else if (!md_util_is_dns_name(p, uri_parsed->hostname, 0)) {
+ else if (!md_dns_is_name(p, uri_parsed->hostname, 0)) {
err = "invalid hostname";
}
if (uri_parsed->port_str
@@ -808,38 +957,37 @@ apr_status_t md_util_exec(apr_pool_t *p,
apr_procattr_t *procattr;
apr_proc_t *proc;
apr_exit_why_e ewhy;
-
+ char buffer[1024];
+
*exit_code = 0;
if (!(proc = apr_pcalloc(p, sizeof(*proc)))) {
return APR_ENOMEM;
}
if ( APR_SUCCESS == (rv = apr_procattr_create(&procattr, p))
&& APR_SUCCESS == (rv = apr_procattr_io_set(procattr, APR_NO_FILE,
- APR_NO_PIPE, APR_NO_PIPE))
+ APR_NO_PIPE, APR_FULL_BLOCK))
&& APR_SUCCESS == (rv = apr_procattr_cmdtype_set(procattr, APR_PROGRAM))
- && APR_SUCCESS == (rv = apr_proc_create(proc, cmd, argv, NULL, procattr, p))
- && APR_CHILD_DONE == (rv = apr_proc_wait(proc, exit_code, &ewhy, APR_WAIT))) {
- /* let's not dwell on exit stati, but core should signal something's bad */
- if (*exit_code > 127 || APR_PROC_SIGNAL_CORE == ewhy) {
- return APR_EINCOMPLETE;
+ && APR_SUCCESS == (rv = apr_proc_create(proc, cmd, argv, NULL, procattr, p))) {
+
+ /* read stderr and log on INFO for possible fault analysis. */
+ while(APR_SUCCESS == (rv = apr_file_gets(buffer, sizeof(buffer)-1, proc->err))) {
+ md_log_perror(MD_LOG_MARK, MD_LOG_INFO, 0, p, "cmd(%s) stderr: %s", cmd, buffer);
+ }
+ if (!APR_STATUS_IS_EOF(rv)) goto out;
+ apr_file_close(proc->err);
+
+ if (APR_CHILD_DONE == (rv = apr_proc_wait(proc, exit_code, &ewhy, APR_WAIT))) {
+ /* let's not dwell on exit stati, but core should signal something's bad */
+ if (*exit_code > 127 || APR_PROC_SIGNAL_CORE == ewhy) {
+ return APR_EINCOMPLETE;
+ }
+ return APR_SUCCESS;
}
- return APR_SUCCESS;
}
+out:
return rv;
}
-
-/* date/time encoding *****************************************************************************/
-
-const char *md_print_duration(apr_pool_t *p, apr_interval_time_t duration)
-{
- int secs = (int)(apr_time_sec(duration) % MD_SECS_PER_DAY);
- return apr_psprintf(p, "%2d:%02d:%02d hours",
- (int)secs/MD_SECS_PER_HOUR, (int)(secs%(MD_SECS_PER_HOUR))/60,
- (int)(secs%60));
-}
-
-
/* base64 url encoding ****************************************************************************/
#define N6 (unsigned int)-1
Modified: httpd/httpd/trunk/modules/md/md_util.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_util.h?rev=1862013&r1=1862012&r2=1862013&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_util.h (original)
+++ httpd/httpd/trunk/modules/md/md_util.h Mon Jun 24 16:04:32 2019
@@ -33,9 +33,28 @@ apr_status_t md_util_pool_do(md_util_act
apr_status_t md_util_pool_vdo(md_util_vaction *cb, void *baton, apr_pool_t *p, ...);
/**************************************************************************************************/
+/* data chunks */
+
+typedef struct md_data md_data;
+struct md_data {
+ const char *data;
+ apr_size_t len;
+};
+
+md_data *md_data_create(apr_pool_t *p, const char *data, apr_size_t len);
+
+apr_status_t md_data_to_hex(const char **phex, char separator,
+ apr_pool_t *p, const md_data *data);
+
+/**************************************************************************************************/
/* string related */
char *md_util_str_tolower(char *s);
+/**
+ * Return != 0 iff array is either NULL or empty
+ */
+int md_array_is_empty(const struct apr_array_header_t *array);
+
int md_array_str_index(const struct apr_array_header_t *array, const char *s,
int start, int case_sensitive);
@@ -44,9 +63,15 @@ int md_array_str_eq(const struct apr_arr
struct apr_array_header_t *md_array_str_clone(apr_pool_t *p, struct apr_array_header_t *array);
+/**
+ * Create a new array with duplicates removed.
+ */
struct apr_array_header_t *md_array_str_compact(apr_pool_t *p, struct apr_array_header_t *src,
int case_sensitive);
+/**
+ * Create a new array with all occurances of <exclude> removed.
+ */
struct apr_array_header_t *md_array_str_remove(apr_pool_t *p, struct apr_array_header_t *src,
const char *exclude, int case_sensitive);
@@ -61,7 +86,41 @@ apr_status_t md_util_exec(apr_pool_t *p,
/**************************************************************************************************/
/* dns name check */
-int md_util_is_dns_name(apr_pool_t *p, const char *hostname, int need_fqdn);
+/**
+ * Is a host/domain name using allowed characters. Not a wildcard.
+ * @param domain name to check
+ * @param need_fqdn iff != 0, check that domain contains '.'
+ * @return != 0 iff domain looks like a non-wildcard, legal DNS domain name.
+ */
+int md_dns_is_name(apr_pool_t *p, const char *domain, int need_fqdn);
+
+/**
+ * Check if the given domain is a valid wildcard DNS name, e.g. *.example.org
+ * @param domain name to check
+ * @return != 0 iff domain is a DNS wildcard.
+ */
+int md_dns_is_wildcard(apr_pool_t *p, const char *domain);
+
+/**
+ * Determine iff pattern matches domain, including case-ignore and wildcard domains.
+ * It is assumed that both names follow dns syntax.
+ * @return != 0 iff pattern matches domain
+ */
+int md_dns_matches(const char *pattern, const char *domain);
+
+/**
+ * Create a new array with the minimal set out of the given domain names that match all
+ * of them. If none of the domains is a wildcard, only duplicates are removed.
+ * If domains contain a wildcard, any name matching the wildcard will be removed.
+ */
+struct apr_array_header_t *md_dns_make_minimal(apr_pool_t *p,
+ struct apr_array_header_t *domains);
+
+/**
+ * Determine if the given domains cover the name, including wildcard matching.
+ * @return != 0 iff name is matched by list of domains
+ */
+int md_dns_domains_match(const apr_array_header_t *domains, const char *name);
/**************************************************************************************************/
/* file system related */
@@ -78,6 +137,7 @@ apr_status_t md_util_path_merge(const ch
apr_status_t md_util_is_dir(const char *path, apr_pool_t *pool);
apr_status_t md_util_is_file(const char *path, apr_pool_t *pool);
+int md_file_exists(const char *fname, apr_pool_t *p);
typedef apr_status_t md_util_file_cb(void *baton, struct apr_file_t *f, apr_pool_t *p);
@@ -137,12 +197,4 @@ apr_status_t md_util_try(md_util_try_fn
apr_interval_time_t timeout, apr_interval_time_t start_delay,
apr_interval_time_t max_delay, int backoff);
-/**************************************************************************************************/
-/* date/time related */
-
-#define MD_SECS_PER_HOUR (60*60)
-#define MD_SECS_PER_DAY (24*MD_SECS_PER_HOUR)
-
-const char *md_print_duration(apr_pool_t *p, apr_interval_time_t duration);
-
#endif /* md_util_h */
Modified: httpd/httpd/trunk/modules/md/md_version.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/md/md_version.h?rev=1862013&r1=1862012&r2=1862013&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/md/md_version.h (original)
+++ httpd/httpd/trunk/modules/md/md_version.h Mon Jun 24 16:04:32 2019
@@ -27,7 +27,7 @@
* @macro
* Version number of the md module as c string
*/
-#define MOD_MD_VERSION "1.1.19-DEV"
+#define MOD_MD_VERSION "2.0.6"
/**
* @macro
@@ -35,8 +35,8 @@
* 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 0x010113
+#define MOD_MD_VERSION_NUM 0x020006
-#define MD_ACME_DEF_URL "https://acme-v01.api.letsencrypt.org/directory"
+#define MD_ACME_DEF_URL "https://acme-v02.api.letsencrypt.org/directory"
#endif /* mod_md_md_version_h */