Apache HTTPD
md_store.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <assert.h>
18#include <stddef.h>
19#include <stdio.h>
20#include <stdlib.h>
21
22#include <apr_lib.h>
23#include <apr_file_info.h>
24#include <apr_file_io.h>
25#include <apr_fnmatch.h>
26#include <apr_hash.h>
27#include <apr_strings.h>
28
29#include "md.h"
30#include "md_crypt.h"
31#include "md_log.h"
32#include "md_json.h"
33#include "md_store.h"
34#include "md_util.h"
35
36/**************************************************************************************************/
37/* generic callback handling */
38
39#define ASPECT_MD "md.json"
40#define ASPECT_CERT "cert.pem"
41#define ASPECT_PKEY "key.pem"
42#define ASPECT_CHAIN "chain.pem"
43
44#define GNAME_ACCOUNTS
45#define GNAME_CHALLENGES
46#define GNAME_DOMAINS
47#define GNAME_STAGING
48#define GNAME_ARCHIVE
49
50static const char *GROUP_NAME[] = {
51 "none",
52 "accounts",
53 "challenges",
54 "domains",
55 "staging",
56 "archive",
57 "tmp",
58 "ocsp",
59 NULL
60};
61
62const char *md_store_group_name(unsigned int group)
63{
64 if (group < sizeof(GROUP_NAME)/sizeof(GROUP_NAME[0])) {
65 return GROUP_NAME[group];
66 }
67 return "UNKNOWN";
68}
69
71 const char *name, const char *aspect,
72 md_store_vtype_t vtype, void **pdata,
74{
75 return store->load(store, group, name, aspect, vtype, pdata, p);
76}
77
79 const char *name, const char *aspect,
80 md_store_vtype_t vtype, void *data,
81 int create)
82{
83 return store->save(store, p, group, name, aspect, vtype, data, create);
84}
85
87 const char *name, const char *aspect,
88 apr_pool_t *p, int force)
89{
90 return store->remove(store, group, name, aspect, p, force);
91}
92
94 const char *name)
95{
96 return store->purge(store, p, group, name);
97}
98
100 apr_pool_t *p, md_store_group_t group, const char *pattern,
101 const char *aspect, md_store_vtype_t vtype)
102{
103 return store->iterate(inspect, baton, store, p, group, pattern, aspect, vtype);
104}
105
107 const char *name, const char *aspect,
108 struct md_json_t **pdata, apr_pool_t *p)
109{
110 return md_store_load(store, group, name, aspect, MD_SV_JSON, (void**)pdata, p);
111}
112
114 const char *name, const char *aspect,
115 struct md_json_t *data, int create)
116{
117 return md_store_save(store, p, group, name, aspect, MD_SV_JSON, (void*)data, create);
118}
119
122 const char *name, int archive)
123{
124 return store->move(store, p, from, to, name, archive);
125}
126
128 md_store_t *store, md_store_group_t group,
129 const char *name, const char *aspect,
130 apr_pool_t *p)
131{
132 if (store->get_fname) {
133 return store->get_fname(pfname, store, group, name, aspect, p);
134 }
135 return APR_ENOTIMPL;
136}
137
139 const char *name, const char *aspect, apr_pool_t *p)
140{
141 return store->is_newer(store, group1, group2, name, aspect, p);
142}
143
145 const char *name, const char *aspect, apr_pool_t *p)
146{
147 return store->get_modified(store, group, name, aspect, p);
148}
149
151 apr_pool_t *p, md_store_group_t group, const char *pattern)
152{
153 return store->iterate_names(inspect, baton, store, p, group, pattern);
154}
155
157 apr_time_t modified,
158 md_store_group_t group,
159 const char *name,
160 const char *aspect)
161{
162 return store->remove_nms(store, p, modified, group, name, aspect);
163}
164
166 md_store_group_t group, const char *name, const char *to)
167{
168 return store->rename(store, p, group, name, to);
169}
170
171/**************************************************************************************************/
172/* convenience */
173
178
180 const char *name, md_t **pmd, apr_pool_t *p)
181{
182 md_json_t *json;
183 apr_status_t rv;
184
185 rv = md_store_load_json(store, group, name, MD_FN_MD, pmd? &json : NULL, p);
186 if (APR_SUCCESS == rv) {
187 if (pmd) {
188 *pmd = md_from_json(json, p);
189 }
190 return APR_SUCCESS;
191 }
192 return rv;
193}
194
196{
198 md_json_t *json;
199 md_t *md;
200 int create;
201
202 md = va_arg(ap, md_t *);
203 create = va_arg(ap, int);
204
205 json = md_to_json(md, ptemp);
206 assert(json);
207 assert(md->name);
208 return md_store_save_json(ctx->store, p, ctx->group, md->name, MD_FN_MD, json, create);
209}
210
212 md_store_group_t group, md_t *md, int create)
213{
215
216 ctx.store = store;
217 ctx.group = group;
218 return md_util_pool_vdo(p_save, &ctx, p, md, create, NULL);
219}
220
222{
224 const char *name;
225 int force;
226
227 (void)p;
228 name = va_arg(ap, const char *);
229 force = va_arg(ap, int);
230
231 assert(name);
232 return md_store_remove(ctx->store, ctx->group, name, MD_FN_MD, ptemp, force);
233}
234
236 md_store_group_t group, const char *name, int force)
237{
239
240 ctx.store = store;
241 ctx.group = group;
243}
244
250
251
256
257static const char *pk_filename(const char *keyname, const char *base, apr_pool_t *p)
258{
259 char *s, *t;
260 /* We also run on various filesystems with difference upper/lower preserve matching
261 * rules. Normalize the names we use, since private key specifications are basically
262 * user input. */
263 s = (keyname && apr_strnatcasecmp("rsa", keyname))?
264 apr_pstrcat(p, base, ".", keyname, ".pem", NULL)
265 : apr_pstrcat(p, base, ".pem", NULL);
266 for (t = s; *t; t++ )
267 *t = (char)apr_tolower(*t);
268 return s;
269}
270
272{
273 return pk_filename(md_pkey_spec_name(spec), "privkey", p);
274}
275
277{
278 return pk_filename(md_pkey_spec_name(spec), "pubcert", p);
279}
280
283{
284 const char *fname = md_pkey_filename(spec, p);
285 return md_store_load(store, group, name, fname, MD_SV_PKEY, (void**)ppkey, p);
286}
287
289 md_pkey_spec_t *spec, struct md_pkey_t *pkey, int create)
290{
291 const char *fname = md_pkey_filename(spec, p);
292 return md_store_save(store, p, group, name, fname, MD_SV_PKEY, pkey, create);
293}
294
297 apr_pool_t *p)
298{
299 const char *fname = md_chain_filename(spec, p);
300 return md_store_load(store, group, name, fname, MD_SV_CHAIN, (void**)ppubcert, p);
301}
302
304 md_store_group_t group, const char *name,
305 md_pkey_spec_t *spec, struct apr_array_header_t *pubcert, int create)
306{
307 const char *fname = md_chain_filename(spec, p);
308 return md_store_save(store, p, group, name, fname, MD_SV_CHAIN, pubcert, create);
309}
310
313{
314 md_credentials_t *creds = apr_pcalloc(p, sizeof(*creds));
315 apr_status_t rv;
316
317 creds->spec = spec;
318 if (APR_SUCCESS != (rv = md_pkey_load(store, group, name, spec, &creds->pkey, p))) {
319 goto leave;
320 }
321 /* chain is optional */
322 rv = md_pubcert_load(store, group, name, spec, &creds->chain, p);
323 if (APR_STATUS_IS_ENOENT(rv)) rv = APR_SUCCESS;
324leave:
325 *pcreds = (APR_SUCCESS == rv)? creds : NULL;
326 return rv;
327}
328
330 const char *name, md_credentials_t *creds, int create)
331{
332 apr_status_t rv;
333
334 if (APR_SUCCESS != (rv = md_pkey_save(store, p, group, name, creds->spec, creds->pkey, create))) {
335 goto leave;
336 }
337 rv = md_pubcert_save(store, p, group, name, creds->spec, creds->chain, create);
338leave:
339 return rv;
340}
341
350
351static int insp_md(void *baton, const char *name, const char *aspect,
352 md_store_vtype_t vtype, void *value, apr_pool_t *ptemp)
353{
355
356 if (!strcmp(MD_FN_MD, aspect) && vtype == MD_SV_JSON) {
357 md_t *md = md_from_json(value, ptemp);
358 md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting md at: %s", name);
359 return ctx->inspect(ctx->baton, ctx->store, md, ptemp);
360 }
361 return 1;
362}
363
365 apr_pool_t *p, md_store_group_t group, const char *pattern)
366{
368
369 ctx.store = store;
370 ctx.group = group;
371 ctx.inspect = inspect;
372 ctx.baton = baton;
373
374 return md_store_iter(insp_md, &ctx, store, p, group, pattern, MD_FN_MD, MD_SV_JSON);
375}
376
381
383{
384 store->unlock_global(store, p);
385}
const char * pattern
Definition ap_regex.h:243
APR File Information.
APR File I/O Handling.
APR FNMatch Functions.
APR Hash Tables.
APR general purpose library routines.
APR Strings library.
ap_conf_vector_t * base
ap_vhost_iterate_conn_cb void * baton
Definition http_vhost.h:87
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_STATUS_IS_ENOENT(s)
Definition apr_errno.h:1246
apr_brigade_flush void * ctx
apr_datum_t * pkey
Definition apr_dbm.h:158
apr_size_t size
#define apr_tolower(c)
Definition apr_lib.h:231
const char * value
Definition apr_env.h:51
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
void * data
const char * fname
apr_vformatter_buff_t const char va_list ap
Definition apr_lib.h:176
apr_interval_time_t t
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
int to
const char * s
Definition apr_strings.h:95
apr_int64_t apr_time_t
Definition apr_time.h:45
struct md_json_t * md_to_json(const md_t *md, apr_pool_t *p)
Definition md_core.c:268
md_t * md_from_json(struct md_json_t *json, apr_pool_t *p)
Definition md_core.c:325
const char * md_pkey_spec_name(const md_pkey_spec_t *spec)
Definition md_crypt.c:520
apr_pool_t * p
Definition md_event.c:32
void md_log_perror(const char *file, int line, md_log_level_t level, apr_status_t rv, apr_pool_t *p, const char *fmt,...)
Definition md_log.c:68
#define MD_LOG_MARK
Definition md_log.h:39
@ MD_LOG_TRACE3
Definition md_log.h:31
static const char * pk_filename(const char *keyname, const char *base, apr_pool_t *p)
Definition md_store.c:257
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)
Definition md_store.c:78
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)
Definition md_store.c:113
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)
Definition md_store.c:99
static apr_status_t p_remove(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
Definition md_store.c:221
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)
Definition md_store.c:329
apr_status_t md_creds_load(md_store_t *store, md_store_group_t group, const char *name, md_pkey_spec_t *spec, md_credentials_t **pcreds, apr_pool_t *p)
Definition md_store.c:311
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)
Definition md_store.c:364
const char * md_pkey_filename(md_pkey_spec_t *spec, apr_pool_t *p)
Definition md_store.c:271
apr_status_t md_pubcert_load(md_store_t *store, md_store_group_t group, const char *name, md_pkey_spec_t *spec, struct apr_array_header_t **ppubcert, apr_pool_t *p)
Definition md_store.c:295
static const char * GROUP_NAME[]
Definition md_store.c:50
apr_status_t md_pubcert_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name, md_pkey_spec_t *spec, struct apr_array_header_t *pubcert, int create)
Definition md_store.c:303
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)
Definition md_store.c:150
void md_store_unlock_global(md_store_t *store, apr_pool_t *p)
Definition md_store.c:382
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)
Definition md_store.c:144
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)
Definition md_store.c:86
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)
Definition md_store.c:127
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)
Definition md_store.c:138
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)
Definition md_store.c:245
const char * md_chain_filename(md_pkey_spec_t *spec, apr_pool_t *p)
Definition md_store.c:276
apr_status_t md_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, md_t *md, int create)
Definition md_store.c:211
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)
Definition md_store.c:156
apr_status_t md_store_lock_global(md_store_t *store, apr_pool_t *p, apr_time_t max_wait)
Definition md_store.c:377
apr_status_t md_store_purge(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name)
Definition md_store.c:93
const char * md_store_group_name(unsigned int group)
Definition md_store.c:62
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)
Definition md_store.c:106
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)
Definition md_store.c:120
static apr_status_t p_save(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
Definition md_store.c:195
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)
Definition md_store.c:165
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)
Definition md_store.c:70
static int insp_md(void *baton, const char *name, const char *aspect, md_store_vtype_t vtype, void *value, apr_pool_t *ptemp)
Definition md_store.c:351
apr_status_t md_remove(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name, int force)
Definition md_store.c:235
apr_status_t md_pkey_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name, md_pkey_spec_t *spec, struct md_pkey_t *pkey, int create)
Definition md_store.c:288
apr_status_t md_load(md_store_t *store, md_store_group_t group, const char *name, md_t **pmd, apr_pool_t *p)
Definition md_store.c:179
apr_status_t md_pkey_load(md_store_t *store, md_store_group_t group, const char *name, md_pkey_spec_t *spec, md_pkey_t **ppkey, apr_pool_t *p)
Definition md_store.c:281
md_store_group_t
Definition md_store.h:62
md_store_vtype_t
Definition md_store.h:52
@ MD_SV_PKEY
Definition md_store.h:56
@ MD_SV_JSON
Definition md_store.h:54
@ MD_SV_CHAIN
Definition md_store.h:57
int md_store_md_inspect(void *baton, md_store_t *store, md_t *md, apr_pool_t *ptemp)
Definition md_store.h:238
int md_store_inspect(void *baton, const char *name, const char *aspect, md_store_vtype_t vtype, void *value, apr_pool_t *ptemp)
Definition md_store.h:152
#define MD_FN_MD
Definition md_store.h:74
apr_status_t md_util_pool_vdo(md_util_vaction *cb, void *baton, apr_pool_t *p,...)
Definition md_util.c:65
return NULL
Definition mod_so.c:359
char * name
const char * pattern
Definition md_store.c:345
md_store_group_t group
Definition md_store.c:344
md_store_md_inspect * inspect
Definition md_store.c:347
const char * aspect
Definition md_store.c:346
md_store_t * store
Definition md_store.c:343
struct apr_array_header_t * chain
Definition md_store.h:269
struct md_pkey_spec_t * spec
Definition md_store.h:267
struct md_pkey_t * pkey
Definition md_store.h:268
md_store_group_t group
Definition md_store.c:176
md_store_t * store
Definition md_store.c:175
apr_array_header_t * mds
Definition md_store.c:254
apr_pool_t * p
Definition md_store.c:253
md_store_unlock_global_cb * unlock_global
Definition md_store.h:339
md_store_rename_cb * rename
Definition md_store.h:330
md_store_iter_cb * iterate
Definition md_store.h:331
md_store_get_fname_cb * get_fname
Definition md_store.h:334
md_store_save_cb * save
Definition md_store.h:326
md_store_get_modified_cb * get_modified
Definition md_store.h:336
md_store_names_iter_cb * iterate_names
Definition md_store.h:332
md_store_remove_nms_cb * remove_nms
Definition md_store.h:337
md_store_remove_cb * remove
Definition md_store.h:328
md_store_load_cb * load
Definition md_store.h:327
md_store_move_cb * move
Definition md_store.h:329
md_store_lock_global_cb * lock_global
Definition md_store.h:338
md_store_is_newer_cb * is_newer
Definition md_store.h:335
md_store_purge_cb * purge
Definition md_store.h:333
Definition md.h:76
const char * name
Definition md.h:77