/* 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_store_h
#define mod_md_md_store_h
struct apr_array_header_t;
struct md_cert_t;
struct md_pkey_t;
struct md_pkey_spec_t;
const char *md_store_group_name(unsigned int group);
typedef struct md_store_t md_store_t;
/**
* A store for domain related data .
*
* The Key for a piece of data is the set of 3 items
* < group > + < domain > + < aspect >
*
* Examples :
* " domains " + " greenbytes . de " + " pubcert . pem "
* " ocsp " + " greenbytes . de " + " ocsp - XXXXX . json "
*
* Storage groups are pre - defined , domain and aspect names can be freely chosen .
*
* Groups reflect use cases and come with security restrictions . The groups
* DOMAINS , ARCHIVE and NONE are only accessible during the startup
* phase of httpd .
*
* Private key are stored unencrypted only in restricted groups . Meaning that certificate
* keys in group DOMAINS are not encrypted , but only readable at httpd start / reload .
* Keys in unrestricted groups are encrypted using a pass phrase generated once and stored
* in NONE .
*/
/** Value types handled by a store */
typedef enum {
MD_SV_TEXT, /* plain text, value is (char*) */
MD_SV_JSON, /* JSON serialization, value is (md_json_t*) */
MD_SV_CERT, /* PEM x509 certificate, value is (md_cert_t*) */
MD_SV_PKEY, /* PEM private key, value is (md_pkey_t*) */
MD_SV_CHAIN, /* list of PEM x509 certificates, value is
(apr_array_header_t*) of (md_cert*) */
} md_store_vtype_t;
/** Store storage groups */
typedef enum {
MD_SG_NONE, /* top level of store, name MUST be NULL in calls */
MD_SG_ACCOUNTS, /* ACME accounts */
MD_SG_CHALLENGES, /* challenge response data for a domain */
MD_SG_DOMAINS, /* live certificates and settings for a domain */
MD_SG_STAGING, /* staged set of certificate and settings, maybe incomplete */
MD_SG_ARCHIVE, /* Archived live sets of a domain */
MD_SG_TMP, /* temporary domain storage */
MD_SG_OCSP, /* OCSP stapling related domain data */
MD_SG_COUNT, /* number of storage groups, used in setups */
} md_store_group_t;
#define MD_FN_MD "md.json"
#define MD_FN_JOB "job.json"
#define MD_FN_HTTPD_JSON "httpd.json"
/* The corresponding names for current cert & key files are constructed
* in md_store and md_crypt .
*/
/* These three legacy filenames are only used in md_store_fs to
* upgrade 1 . 0 directories . They should not be used for any other
* purpose .
*/
#define MD_FN_PRIVKEY "privkey.pem"
#define MD_FN_PUBCERT "pubcert.pem"
#define MD_FN_CERT "cert.pem"
/**
* Load the JSON value at key " group / name / aspect " , allocated from pool p .
* @ return APR_ENOENT if there is no such value
*/
apr_status_t md_store_load_json(md_store_t *store, md_store_group_t group,
const char *name, const char *aspect,
struct md_json_t **pdata, apr_pool_t *p);
/**
* Save the JSON value at key " group / name / aspect " . If create ! = 0 , fail if there
* already is a value for this key .
*/
apr_status_t md_store_save_json(md_store_t *store, apr_pool_t *p, md_store_group_t group,
const char *name, const char *aspect,
struct md_json_t *data, int create);
/**
* Load the value of type at key " group / name / aspect " , allocated from pool p . Usually , the
* type is expected to be the same as used in saving the value . Some conversions will work ,
* others will fail the format .
* @ return APR_ENOENT if there is no such value
*/
apr_status_t md_store_load(md_store_t *store, md_store_group_t group,
const char *name, const char *aspect,
md_store_vtype_t vtype, void **pdata,
apr_pool_t *p);
/**
* Save the JSON value at key " group / name / aspect " . If create ! = 0 , fail if there
* already is a value for this key . The provided data MUST be of the correct type .
*/
apr_status_t md_store_save(md_store_t *store, apr_pool_t *p, md_store_group_t group,
const char *name, const char *aspect,
md_store_vtype_t vtype, void *data,
int create);
/**
* Remove the value stored at key " group / name / aspect " . Unless force ! = 0 , a missing
* value will cause the call to fail with APR_ENOENT .
*/
apr_status_t md_store_remove(md_store_t *store, md_store_group_t group,
const char *name, const char *aspect,
apr_pool_t *p, int force);
/**
* Remove everything matching key " group / name " .
*/
apr_status_t md_store_purge(md_store_t *store, apr_pool_t *p,
md_store_group_t group, const char *name);
/**
* Remove all items matching the name / aspect patterns that have not been
* modified since the given timestamp .
*/
apr_status_t md_store_remove_not_modified_since(md_store_t *store, apr_pool_t *p,
apr_time_t modified,
md_store_group_t group,
const char *name,
const char *aspect);
/**
* inspect callback function . Invoked for each matched value . Values allocated from
* ptemp may disappear any time after the call returned . If this function returns
* 0 , the iteration is aborted .
*/
typedef int md_store_inspect(void *baton, const char *name, const char *aspect,
md_store_vtype_t vtype, void *value, apr_pool_t *ptemp);
/**
* Iterator over all existing values matching the name pattern . Patterns are evaluated
* using apr_fnmatch ( ) without flags .
*/
apr_status_t md_store_iter(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);
/**
* Move everything matching key " from / name " from one group to another . If archive ! = 0 ,
* move any existing " to / name " into a new " archive / new_name " location .
*/
apr_status_t md_store_move(md_store_t *store, apr_pool_t *p,
md_store_group_t from, md_store_group_t to,
const char *name, int archive);
/**
* Rename a group member .
*/
apr_status_t md_store_rename(md_store_t *store, apr_pool_t *p,
md_store_group_t group, const char *name, const char *to);
/**
* Get the filename of an item stored in " group / name / aspect " . The item does
* not have to exist .
*/
apr_status_t md_store_get_fname(const char **pfname,
md_store_t *store, md_store_group_t group,
const char *name, const char *aspect,
apr_pool_t *p);
/**
* Make a compare on the modification time of " group1 / name / aspect " vs . " group2 / name / aspect " .
*/
int md_store_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,
const char *name, const char *aspect, apr_pool_t *p);
/**
* Iterate over all names that exist in a group , e . g . there are items matching
* " group / pattern " . The inspect function is called with the name and NULL aspect
* and value .
*/
apr_status_t md_store_iter_names(md_store_inspect *inspect, void *baton, md_store_t *store,
apr_pool_t *p, md_store_group_t group, const char *pattern);
/**
* Get the modification time of the item store under " group / name / aspect " .
* @ return modification time or 0 if the item does not exist .
*/
apr_time_t md_store_get_modified(md_store_t *store, md_store_group_t group,
const char *name, const char *aspect, apr_pool_t *p);
/**
* Acquire a cooperative , global lock on store modifications .
* This will only prevent other children / processes / cluster nodes from
* doing the same and does not protect individual store functions from
* being called without it .
* @ param store the store
* @ param p memory pool to use
* @ param max_wait maximum time to wait in order to acquire
* @ return APR_SUCCESS when lock was obtained
*/
apr_status_t md_store_lock_global(md_store_t *store, apr_pool_t *p, apr_time_t max_wait);
/**
* Realease the global store lock . Will do nothing if there is no lock .
*/
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,
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);
apr_status_t md_remove(md_store_t *store, apr_pool_t *p, md_store_group_t group,
const char *name, int force);
int md_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,
const char *name, apr_pool_t *p);
typedef int md_store_md_inspect(void *baton, md_store_t *store, md_t *md, apr_pool_t *ptemp);
apr_status_t md_store_md_iter(md_store_md_inspect *inspect, void *baton, md_store_t *store,
apr_pool_t *p, md_store_group_t group, const char *pattern);
const char *md_pkey_filename(struct md_pkey_spec_t *spec, apr_pool_t *p);
const char *md_chain_filename(struct md_pkey_spec_t *spec, apr_pool_t *p);
apr_status_t md_pkey_load(md_store_t *store, md_store_group_t group,
const char *name, struct md_pkey_spec_t *spec,
struct md_pkey_t **ppkey, apr_pool_t *p);
apr_status_t md_pkey_save(md_store_t *store, apr_pool_t *p, md_store_group_t group,
const char *name, struct md_pkey_spec_t *spec,
struct md_pkey_t *pkey, int create);
apr_status_t md_pubcert_load(md_store_t *store, md_store_group_t group, const char *name,
struct md_pkey_spec_t *spec, struct apr_array_header_t **ppubcert,
apr_pool_t *p);
apr_status_t md_pubcert_save(md_store_t *store, apr_pool_t *p,
md_store_group_t group, const char *name,
struct md_pkey_spec_t *spec,
struct apr_array_header_t *pubcert, int create);
/**************************************************************************************************/
/* X509 complete credentials */
typedef struct md_credentials_t md_credentials_t;
struct md_credentials_t {
struct md_pkey_spec_t *spec;
struct md_pkey_t *pkey;
struct apr_array_header_t *chain;
};
apr_status_t md_creds_load(md_store_t *store, md_store_group_t group, const char *name,
struct md_pkey_spec_t *spec, md_credentials_t **pcreds, apr_pool_t *p);
apr_status_t md_creds_save(md_store_t *store, apr_pool_t *p, md_store_group_t group,
const char *name, md_credentials_t *creds, int create);
/**************************************************************************************************/
/* implementation interface */
typedef apr_status_t md_store_load_cb(md_store_t *store, md_store_group_t group,
const char *name, const char *aspect,
md_store_vtype_t vtype, void **pvalue,
apr_pool_t *p);
typedef apr_status_t md_store_save_cb(md_store_t *store, apr_pool_t *p, md_store_group_t group,
const char *name, const char *aspect,
md_store_vtype_t vtype, void *value,
int create);
typedef apr_status_t md_store_remove_cb(md_store_t *store, md_store_group_t group,
const char *name, const char *aspect,
apr_pool_t *p, int force);
typedef apr_status_t md_store_purge_cb(md_store_t *store, apr_pool_t *p, md_store_group_t group,
const char *name);
typedef apr_status_t md_store_iter_cb(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);
typedef apr_status_t md_store_names_iter_cb(md_store_inspect *inspect, void *baton, md_store_t *store,
apr_pool_t *p, md_store_group_t group, const char *pattern);
typedef apr_status_t md_store_move_cb(md_store_t *store, apr_pool_t *p, md_store_group_t from,
md_store_group_t to, const char *name, int archive);
typedef apr_status_t md_store_rename_cb(md_store_t *store, apr_pool_t *p, md_store_group_t group,
const char *from, const char *to);
typedef apr_status_t md_store_get_fname_cb(const char **pfname,
md_store_t *store, md_store_group_t group,
const char *name, const char *aspect,
apr_pool_t *p);
typedef int md_store_is_newer_cb(md_store_t *store,
md_store_group_t group1, md_store_group_t group2,
const char *name, const char *aspect, apr_pool_t *p);
typedef apr_time_t md_store_get_modified_cb(md_store_t *store, md_store_group_t group,
const char *name, const char *aspect, apr_pool_t *p);
typedef apr_status_t md_store_remove_nms_cb(md_store_t *store, apr_pool_t *p,
apr_time_t modified, md_store_group_t group,
const char *name, const char *aspect);
typedef apr_status_t md_store_lock_global_cb(md_store_t *store, apr_pool_t *p, apr_time_t max_wait);
typedef void md_store_unlock_global_cb(md_store_t *store, apr_pool_t *p);
struct md_store_t {
md_store_save_cb *save;
md_store_load_cb *load;
md_store_remove_cb *remove;
md_store_move_cb *move;
md_store_rename_cb *rename;
md_store_iter_cb *iterate;
md_store_names_iter_cb *iterate_names;
md_store_purge_cb *purge;
md_store_get_fname_cb *get_fname;
md_store_is_newer_cb *is_newer;
md_store_get_modified_cb *get_modified;
md_store_remove_nms_cb *remove_nms;
md_store_lock_global_cb *lock_global;
md_store_unlock_global_cb *unlock_global;
};
#endif /* mod_md_md_store_h */
Messung V0.5 in Prozent C=88 H=100 G=94
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-09-29)
¤
*© Formatika GbR, Deutschland