]> granicus.if.org Git - apache/blob - modules/md/md_store.c
*) mod_md: bringing over v2.0.6 from github.
[apache] / modules / md / md_store.c
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
50 static const char *GROUP_NAME[] = {
51     "none",
52     "accounts",
53     "challenges",
54     "domains",
55     "staging",
56     "archive",
57     "tmp",
58     NULL
59 };
60
61 const char *md_store_group_name(int group)
62 {
63     if ((size_t)group < sizeof(GROUP_NAME)/sizeof(GROUP_NAME[0])) {
64         return GROUP_NAME[group];
65     }
66     return "UNKNOWN";
67 }
68
69 void md_store_destroy(md_store_t *store)
70 {
71     if (store->destroy) store->destroy(store);
72 }
73
74 apr_status_t md_store_load(md_store_t *store, md_store_group_t group, 
75                            const char *name, const char *aspect, 
76                            md_store_vtype_t vtype, void **pdata, 
77                            apr_pool_t *p)
78 {
79     return store->load(store, group, name, aspect, vtype, pdata, p);
80 }
81
82 apr_status_t md_store_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
83                            const char *name, const char *aspect, 
84                            md_store_vtype_t vtype, void *data, 
85                            int create)
86 {
87     return store->save(store, p, group, name, aspect, vtype, data, create);
88 }
89
90 apr_status_t md_store_remove(md_store_t *store, md_store_group_t group, 
91                              const char *name, const char *aspect, 
92                              apr_pool_t *p, int force)
93 {
94     return store->remove(store, group, name, aspect, p, force);
95 }
96
97 apr_status_t md_store_purge(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
98                              const char *name)
99 {
100     return store->purge(store, p, group, name);
101 }
102
103 apr_status_t md_store_iter(md_store_inspect *inspect, void *baton, md_store_t *store, 
104                            apr_pool_t *p, md_store_group_t group, const char *pattern, 
105                            const char *aspect, md_store_vtype_t vtype)
106 {
107     return store->iterate(inspect, baton, store, p, group, pattern, aspect, vtype);
108 }
109
110 apr_status_t md_store_load_json(md_store_t *store, md_store_group_t group, 
111                                 const char *name, const char *aspect, 
112                                 struct md_json_t **pdata, apr_pool_t *p)
113 {
114     return md_store_load(store, group, name, aspect, MD_SV_JSON, (void**)pdata, p);
115 }
116
117 apr_status_t md_store_save_json(md_store_t *store, apr_pool_t *p, md_store_group_t group, 
118                                 const char *name, const char *aspect, 
119                                 struct md_json_t *data, int create)
120 {
121     return md_store_save(store, p, group, name, aspect, MD_SV_JSON, (void*)data, create);
122 }
123
124 apr_status_t md_store_move(md_store_t *store, apr_pool_t *p, 
125                            md_store_group_t from, md_store_group_t to,
126                            const char *name, int archive)
127 {
128     return store->move(store, p, from, to, name, archive);
129 }
130
131 apr_status_t md_store_get_fname(const char **pfname, 
132                                 md_store_t *store, md_store_group_t group, 
133                                 const char *name, const char *aspect, 
134                                 apr_pool_t *p)
135 {
136     if (store->get_fname) {
137         return store->get_fname(pfname, store, group, name, aspect, p);
138     }
139     return APR_ENOTIMPL;
140 }
141
142 int md_store_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,  
143                       const char *name, const char *aspect, apr_pool_t *p)
144 {
145     return store->is_newer(store, group1, group2, name, aspect, p);
146 }
147
148 apr_status_t md_store_iter_names(md_store_inspect *inspect, void *baton, md_store_t *store, 
149                                  apr_pool_t *p, md_store_group_t group, const char *pattern)
150 {
151     return store->iterate_names(inspect, baton, store, p, group, pattern);
152 }
153
154 /**************************************************************************************************/
155 /* convenience */
156
157 typedef struct {
158     md_store_t *store;
159     md_store_group_t group;
160 } md_group_ctx;
161
162 apr_status_t md_load(md_store_t *store, md_store_group_t group, 
163                      const char *name, md_t **pmd, apr_pool_t *p)
164 {
165     md_json_t *json;
166     apr_status_t rv;
167     
168     rv = md_store_load_json(store, group, name, MD_FN_MD, pmd? &json : NULL, p);
169     if (APR_SUCCESS == rv) {
170         if (pmd) {
171             *pmd = md_from_json(json, p);
172         }
173         return APR_SUCCESS;
174     }
175     return rv;
176 }
177
178 static apr_status_t p_save(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
179 {
180     md_group_ctx *ctx = baton;
181     md_json_t *json;
182     md_t *md;
183     int create;
184     
185     md = va_arg(ap, md_t *);
186     create = va_arg(ap, int);
187
188     json = md_to_json(md, ptemp);
189     assert(json);
190     assert(md->name);
191     return md_store_save_json(ctx->store, p, ctx->group, md->name, MD_FN_MD, json, create);
192 }
193
194 apr_status_t md_save(md_store_t *store, apr_pool_t *p, 
195                      md_store_group_t group, md_t *md, int create)
196 {
197     md_group_ctx ctx;
198     
199     ctx.store = store;
200     ctx.group = group;
201     return md_util_pool_vdo(p_save, &ctx, p, md, create, NULL);
202 }
203
204 static apr_status_t p_remove(void *baton, apr_pool_t *p, apr_pool_t *ptemp, va_list ap)
205 {
206     md_group_ctx *ctx = baton;
207     const char *name;
208     int force;
209     
210     (void)p;
211     name = va_arg(ap, const char *);
212     force = va_arg(ap, int);
213
214     assert(name);
215     return md_store_remove(ctx->store, ctx->group, name, MD_FN_MD, ptemp, force);
216 }
217
218 apr_status_t md_remove(md_store_t *store, apr_pool_t *p, 
219                        md_store_group_t group, const char *name, int force)
220 {
221     md_group_ctx ctx;
222     
223     ctx.store = store;
224     ctx.group = group;
225     return md_util_pool_vdo(p_remove, &ctx, p, name, force, NULL);
226 }
227
228 int md_is_newer(md_store_t *store, md_store_group_t group1, md_store_group_t group2,  
229                       const char *name, apr_pool_t *p)
230 {
231     return md_store_is_newer(store, group1, group2, name, MD_FN_MD, p);
232 }
233
234
235 typedef struct {
236     apr_pool_t *p;
237     apr_array_header_t *mds;
238 } md_load_ctx;
239
240 apr_status_t md_pkey_load(md_store_t *store, md_store_group_t group, const char *name, 
241                           md_pkey_t **ppkey, apr_pool_t *p)
242 {
243     return md_store_load(store, group, name, MD_FN_PRIVKEY, MD_SV_PKEY, (void**)ppkey, p);
244 }
245
246 apr_status_t md_pkey_save(md_store_t *store, apr_pool_t *p, md_store_group_t group, const char *name, 
247                           struct md_pkey_t *pkey, int create)
248 {
249     return md_store_save(store, p, group, name, MD_FN_PRIVKEY, MD_SV_PKEY, pkey, create);
250 }
251
252 apr_status_t md_pubcert_load(md_store_t *store, md_store_group_t group, const char *name, 
253                              struct apr_array_header_t **ppubcert, apr_pool_t *p)
254 {
255     return md_store_load(store, group, name, MD_FN_PUBCERT, MD_SV_CHAIN, (void**)ppubcert, p);
256 }
257
258 apr_status_t md_pubcert_save(md_store_t *store, apr_pool_t *p, 
259                              md_store_group_t group, const char *name, 
260                              struct apr_array_header_t *pubcert, int create)
261 {
262     return md_store_save(store, p, group, name, MD_FN_PUBCERT, MD_SV_CHAIN, pubcert, create);
263 }
264
265 typedef struct {
266     md_store_t *store;
267     md_store_group_t group;
268     const char *pattern;
269     const char *aspect;
270     md_store_md_inspect *inspect;
271     void *baton;
272 } inspect_md_ctx;
273
274 static int insp_md(void *baton, const char *name, const char *aspect, 
275                    md_store_vtype_t vtype, void *value, apr_pool_t *ptemp)
276 {
277     inspect_md_ctx *ctx = baton;
278     
279     if (!strcmp(MD_FN_MD, aspect) && vtype == MD_SV_JSON) {
280         md_t *md = md_from_json(value, ptemp);
281         md_log_perror(MD_LOG_MARK, MD_LOG_TRACE3, 0, ptemp, "inspecting md at: %s", name);
282         return ctx->inspect(ctx->baton, ctx->store, md, ptemp);
283     }
284     return 1;
285 }
286
287 apr_status_t md_store_md_iter(md_store_md_inspect *inspect, void *baton, md_store_t *store, 
288                               apr_pool_t *p, md_store_group_t group, const char *pattern)
289 {
290     inspect_md_ctx ctx;
291     
292     ctx.store = store;
293     ctx.group = group;
294     ctx.inspect = inspect;
295     ctx.baton = baton;
296     
297     return md_store_iter(insp_md, &ctx, store, p, group, pattern, MD_FN_MD, MD_SV_JSON);
298 }
299