]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
*) mod_md: update to version 2.6.10 trunk trunk
authorStefan Eissing <icing@apache.org>
Mon, 13 Apr 2026 09:05:23 +0000 (09:05 +0000)
committerStefan Eissing <icing@apache.org>
Mon, 13 Apr 2026 09:05:23 +0000 (09:05 +0000)
     - Fix issue #420 <https://github.com/icing/mod_md/issues/420> by ignoring
       job.json files that claim to have completely finished a certificate
       renewal, but have not produced the necessary result files.

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

changes-entries/md_v2.6.10.txt [new file with mode: 0644]
modules/md/md_status.c
modules/md/md_store.c
modules/md/md_store.h
modules/md/md_version.h

diff --git a/changes-entries/md_v2.6.10.txt b/changes-entries/md_v2.6.10.txt
new file mode 100644 (file)
index 0000000..d9e6a02
--- /dev/null
@@ -0,0 +1,4 @@
+  *) mod_md: update to version 2.6.10
+     - Fix issue #420 <https://github.com/icing/mod_md/issues/420> by ignoring
+       job.json files that claim to have completely finished a certificate
+       renewal, but have not produced the necessary result files.
index 3572168081bb737397508630aa89a3382e3007b2..da89b832ca27761ac613665f9a0575b9f1871e8a 100644 (file)
@@ -97,6 +97,31 @@ leave:
     return rv;
 }
 
+static int md_job_json_seems_valid(md_json_t *json, md_store_t *store,
+                                   md_store_group_t group, const char *name,
+                                   apr_pool_t *p)
+{
+
+    if (!json) return FALSE;
+    if ((group == MD_SG_STAGING) &&
+        md_json_getb(json, MD_KEY_FINISHED, NULL) &&
+        md_json_getb(json, MD_KEY_NOTIFIED_RENEWED, NULL)) {
+        md_t *md;
+        /* A finished job in the staging area needs to have produced results */
+        if(!md_exists(store, group, name, p)) return FALSE;
+
+        if (APR_SUCCESS == md_load(store, MD_SG_DOMAINS, name, &md, p)) {
+            int i;
+            for (i = 0; i < md_cert_count(md); ++i) {
+                md_pkey_spec_t *spec = md_pkeys_spec_get(md->pks, i);
+                if(md_pubcert_load(store, group, name, spec, NULL, p) != APR_SUCCESS)
+                    return FALSE;
+            }
+        }
+    }
+    return TRUE;
+}
+
 static apr_status_t job_loadj(md_json_t **pjson, md_store_group_t group, const char *name,
                               struct md_reg_t *reg, int with_log, apr_pool_t *p)
 {
@@ -104,7 +129,13 @@ static apr_status_t job_loadj(md_json_t **pjson, md_store_group_t group, const c
 
     md_store_t *store = md_reg_store_get(reg);
     rv = md_store_load_json(store, group, name, MD_FN_JOB, pjson, p);
-    if (APR_SUCCESS == rv && !with_log) md_json_del(*pjson, MD_KEY_LOG, NULL);
+    if (APR_SUCCESS == rv) {
+        if (!md_job_json_seems_valid(*pjson, store, group, name, p)) {
+          *pjson = NULL;
+          return APR_ENOENT;
+        }
+        if(!with_log) md_json_del(*pjson, MD_KEY_LOG, NULL);
+    }
     return rv;
 }
 
@@ -384,7 +415,8 @@ apr_status_t md_job_load(md_job_t *job)
     apr_status_t rv;
     
     rv = md_store_load_json(job->store, job->group, job->mdomain, MD_FN_JOB, &jprops, job->p);
-    if (APR_SUCCESS == rv) {
+    if ((APR_SUCCESS == rv) &&
+        md_job_json_seems_valid(jprops, job->store, job->group, job->mdomain, job->p)) {
         md_job_from_json(job, jprops, job->p);
     }
     return rv;
index 1ba42946e51ebd20dd770effc871a1886f421648..5ed0848f991c0df3946862cd8ee7db11d6b610c2 100644 (file)
@@ -176,6 +176,12 @@ typedef struct {
     md_store_group_t group;
 } md_group_ctx;
 
+int md_exists(md_store_t *store, md_store_group_t group,
+              const char *name, apr_pool_t *p)
+{
+    return (md_store_load_json(store, group, name, MD_FN_MD, NULL, p) == APR_SUCCESS);
+}
+
 apr_status_t md_load(md_store_t *store, md_store_group_t group, 
                      const char *name, md_t **pmd, apr_pool_t *p)
 {
index 73c840fc57f6205a693feb2b10898bb580744f99..76dd2c3e6e71f119c4d73f20ad3b58db839190d5 100644 (file)
@@ -225,7 +225,9 @@ void md_store_unlock_global(md_store_t *store, apr_pool_t *p);
 /**************************************************************************************************/
 /* Storage handling utils */
 
-apr_status_t md_load(md_store_t *store, md_store_group_t group, 
+int md_exists(md_store_t *store, md_store_group_t group,
+              const char *name, apr_pool_t *p);
+apr_status_t md_load(md_store_t *store, md_store_group_t group,
                      const char *name, md_t **pmd, apr_pool_t *p);
 apr_status_t md_save(struct md_store_t *store, apr_pool_t *p, md_store_group_t group, 
                      md_t *md, int create);
index 7a05c09ab96bc02edcf0fea01f15360651df5f8c..ace0946095bb69981c1d497bd6b3fb1b33521a78 100644 (file)
@@ -27,7 +27,7 @@
  * @macro
  * Version number of the md module as c string
  */
-#define MOD_MD_VERSION "2.6.9"
+#define MOD_MD_VERSION "2.6.10"
 
 /**
  * @macro
@@ -35,7 +35,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 0x020609
+#define MOD_MD_VERSION_NUM 0x02060a
 
 #define MD_ACME_DEF_URL         "https://acme-v02.api.letsencrypt.org/directory"