1 /*
2  * WebAuth context creation and destruction.
3  *
4  * Interfaces for creating and destroying the WebAuth context, which holds any
5  * state required by the WebAuth APIs.
6  *
7  * Written by Russ Allbery <eagle@eyrie.org>
8  * Copyright 2011, 2012, 2013
9  *     The Board of Trustees of the Leland Stanford Junior University
10  *
11  * See LICENSE for licensing terms.
12  */
13 
14 #include <config.h>
15 #include <portable/apr.h>
16 #include <portable/system.h>
17 
18 #include <lib/internal.h>
19 #include <webauth/basic.h>
20 #include <util/macros.h>
21 
22 
23 /*
24  * Given a pool, allocate a WebAuth context from that pool and return it.
25  */
26 static struct webauth_context *
init_context(apr_pool_t * pool)27 init_context(apr_pool_t *pool)
28 {
29     struct webauth_context *ctx;
30 
31     ctx = apr_pcalloc(pool, sizeof(struct webauth_context));
32     ctx->pool = pool;
33     return ctx;
34 }
35 
36 
37 /*
38  * The abort function called by APR on any memory allocation failure.  By
39  * default, APR just returns NULL, which will probably cause segfaults but
40  * might cause some strange issue.  Instead, always abort immediately after
41  * attempting to report an error.
42  */
43 static int
pool_failure(int retcode)44 pool_failure(int retcode)
45 {
46     fprintf(stderr, "libwebauth: APR pool allocation failure (%d)", retcode);
47     abort();
48 
49     /* Not reached. */
50     return retcode;
51 }
52 
53 
54 /*
55  * Initialize a WebAuth context.  This allocates the internal webauth_context
56  * struct and does any necessary initialization, including setting up an APR
57  * memory pool to use for any required allocations.  This is the entry point
58  * for non-APR-aware applications, which hides the APR initialization.  Any
59  * call to this function must be matched one-to-one with a call to
60  * webauth_context_free.
61  */
62 int
webauth_context_init(struct webauth_context ** context,apr_pool_t * parent)63 webauth_context_init(struct webauth_context **context, apr_pool_t *parent)
64 {
65     apr_pool_t *pool;
66 
67     if (apr_initialize() != APR_SUCCESS)
68         return WA_ERR_APR;
69     if (apr_pool_create(&pool, parent) != APR_SUCCESS)
70         return WA_ERR_APR;
71     apr_pool_abort_set(pool_failure, pool);
72     *context = init_context(pool);
73     return WA_ERR_NONE;
74 }
75 
76 
77 /*
78  * Initialize a WebAuth context from inside an APR-aware application.  This
79  * allocates the internal webauth_context struct and does any necessary
80  * initialization, including setting up an APR memory pool to use for any
81  * required allocations.
82  *
83  * This is identical to webauth_context_init except that it doesn't call
84  * apr_initialize and therefore doesn't have to be matched with a call to
85  * webauth_context_free.  A parent pool must be provided.
86  */
87 int
webauth_context_init_apr(struct webauth_context ** context,apr_pool_t * parent)88 webauth_context_init_apr(struct webauth_context **context, apr_pool_t *parent)
89 {
90     apr_pool_t *pool;
91 
92     if (parent == NULL)
93         return WA_ERR_APR;
94     if (apr_pool_create(&pool, parent) != APR_SUCCESS)
95         return WA_ERR_APR;
96     apr_pool_abort_set(pool_failure, pool);
97     *context = init_context(pool);
98     return WA_ERR_NONE;
99 }
100 
101 
102 /*
103  * Free the WebAuth context and its corresponding subpool, which will free all
104  * memory that was allocated from that context.  This should only be called by
105  * applications that use webauth_context_init, not by anything that called
106  * webauth_context_init_apr.
107  */
108 void
webauth_context_free(struct webauth_context * ctx UNUSED)109 webauth_context_free(struct webauth_context *ctx UNUSED)
110 {
111     apr_terminate();
112 }
113