diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-10-25 19:21:04 (GMT) |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2010-10-25 19:21:04 (GMT) |
commit | e02dd8c03ce5b66c81a47830eebe73a21ce71002 (patch) | |
tree | 6b35cc9815eb90b4cf9d97d7f981aff764eeb0ea /src | |
parent | 62def2f82df4b35b03843063364533bd36646ee0 (diff) |
indented code
Diffstat (limited to 'src')
-rw-r--r-- | src/gnutls_cache.c | 925 | ||||
-rw-r--r-- | src/gnutls_config.c | 1039 | ||||
-rw-r--r-- | src/gnutls_hooks.c | 1944 | ||||
-rw-r--r-- | src/gnutls_io.c | 1367 | ||||
-rw-r--r-- | src/gnutls_lua.c | 465 | ||||
-rw-r--r-- | src/mod_gnutls.c | 253 |
6 files changed, 3101 insertions, 2892 deletions
diff --git a/src/gnutls_cache.c b/src/gnutls_cache.c index 90ea440..cbf879c 100644 --- a/src/gnutls_cache.c +++ b/src/gnutls_cache.c | |||
@@ -44,18 +44,18 @@ | |||
44 | #endif | 44 | #endif |
45 | 45 | ||
46 | char *mgs_session_id2sz(unsigned char *id, int idlen, | 46 | char *mgs_session_id2sz(unsigned char *id, int idlen, |
47 | char *str, int strsize) | 47 | char *str, int strsize) |
48 | { | 48 | { |
49 | char *cp; | 49 | char *cp; |
50 | int n; | 50 | int n; |
51 | 51 | ||
52 | cp = str; | 52 | cp = str; |
53 | for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) { | 53 | for (n = 0; n < idlen && n < GNUTLS_MAX_SESSION_ID; n++) { |
54 | apr_snprintf(cp, strsize - (cp-str), "%02X", id[n]); | 54 | apr_snprintf(cp, strsize - (cp - str), "%02X", id[n]); |
55 | cp += 2; | 55 | cp += 2; |
56 | } | 56 | } |
57 | *cp = '\0'; | 57 | *cp = '\0'; |
58 | return str; | 58 | return str; |
59 | } | 59 | } |
60 | 60 | ||
61 | 61 | ||
@@ -63,35 +63,38 @@ char *mgs_session_id2sz(unsigned char *id, int idlen, | |||
63 | * server:port.SessionID | 63 | * server:port.SessionID |
64 | * to disallow resuming sessions on different servers | 64 | * to disallow resuming sessions on different servers |
65 | */ | 65 | */ |
66 | static int mgs_session_id2dbm(conn_rec* c, unsigned char *id, int idlen, | 66 | static int mgs_session_id2dbm(conn_rec * c, unsigned char *id, int idlen, |
67 | apr_datum_t* dbmkey) | 67 | apr_datum_t * dbmkey) |
68 | { | 68 | { |
69 | char buf[STR_SESSION_LEN]; | 69 | char buf[STR_SESSION_LEN]; |
70 | char *sz; | 70 | char *sz; |
71 | 71 | ||
72 | sz = mgs_session_id2sz(id, idlen, buf, sizeof(buf)); | 72 | sz = mgs_session_id2sz(id, idlen, buf, sizeof(buf)); |
73 | if (sz == NULL) | 73 | if (sz == NULL) |
74 | return -1; | 74 | return -1; |
75 | 75 | ||
76 | dbmkey->dptr = apr_psprintf(c->pool, "%s:%d.%s", c->base_server->server_hostname, c->base_server->port, sz); | 76 | dbmkey->dptr = |
77 | dbmkey->dsize = strlen( dbmkey->dptr); | 77 | apr_psprintf(c->pool, "%s:%d.%s", |
78 | 78 | c->base_server->server_hostname, | |
79 | return 0; | 79 | c->base_server->port, sz); |
80 | dbmkey->dsize = strlen(dbmkey->dptr); | ||
81 | |||
82 | return 0; | ||
80 | } | 83 | } |
81 | 84 | ||
82 | #define CTIME "%b %d %k:%M:%S %Y %Z" | 85 | #define CTIME "%b %d %k:%M:%S %Y %Z" |
83 | char *mgs_time2sz(time_t in_time, char *str, int strsize) | 86 | char *mgs_time2sz(time_t in_time, char *str, int strsize) |
84 | { | 87 | { |
85 | apr_time_exp_t vtm; | 88 | apr_time_exp_t vtm; |
86 | apr_size_t ret_size; | 89 | apr_size_t ret_size; |
87 | apr_time_t t; | 90 | apr_time_t t; |
88 | 91 | ||
89 | 92 | ||
90 | apr_time_ansi_put (&t, in_time); | 93 | apr_time_ansi_put(&t, in_time); |
91 | apr_time_exp_gmt (&vtm, t); | 94 | apr_time_exp_gmt(&vtm, t); |
92 | apr_strftime(str, &ret_size, strsize-1, CTIME, &vtm); | 95 | apr_strftime(str, &ret_size, strsize - 1, CTIME, &vtm); |
93 | 96 | ||
94 | return str; | 97 | return str; |
95 | } | 98 | } |
96 | 99 | ||
97 | #if HAVE_APR_MEMCACHE | 100 | #if HAVE_APR_MEMCACHE |
@@ -99,16 +102,18 @@ char *mgs_time2sz(time_t in_time, char *str, int strsize) | |||
99 | * server:port.SessionID | 102 | * server:port.SessionID |
100 | * to disallow resuming sessions on different servers | 103 | * to disallow resuming sessions on different servers |
101 | */ | 104 | */ |
102 | static char* mgs_session_id2mc(conn_rec* c, unsigned char *id, int idlen) | 105 | static char *mgs_session_id2mc(conn_rec * c, unsigned char *id, int idlen) |
103 | { | 106 | { |
104 | char buf[STR_SESSION_LEN]; | 107 | char buf[STR_SESSION_LEN]; |
105 | char *sz; | 108 | char *sz; |
106 | 109 | ||
107 | sz = mgs_session_id2sz(id, idlen, buf, sizeof(buf)); | 110 | sz = mgs_session_id2sz(id, idlen, buf, sizeof(buf)); |
108 | if (sz == NULL) | 111 | if (sz == NULL) |
109 | return NULL; | 112 | return NULL; |
110 | 113 | ||
111 | return apr_psprintf(c->pool, MC_TAG"%s:%d.%s", c->base_server->server_hostname, c->base_server->port, sz); | 114 | return apr_psprintf(c->pool, MC_TAG "%s:%d.%s", |
115 | c->base_server->server_hostname, | ||
116 | c->base_server->port, sz); | ||
112 | } | 117 | } |
113 | 118 | ||
114 | /** | 119 | /** |
@@ -117,482 +122,498 @@ char *sz; | |||
117 | */ | 122 | */ |
118 | 123 | ||
119 | /* The underlying apr_memcache system is thread safe... woohoo */ | 124 | /* The underlying apr_memcache system is thread safe... woohoo */ |
120 | static apr_memcache_t* mc; | 125 | static apr_memcache_t *mc; |
121 | 126 | ||
122 | static int mc_cache_child_init(apr_pool_t *p, server_rec *s, | 127 | static int mc_cache_child_init(apr_pool_t * p, server_rec * s, |
123 | mgs_srvconf_rec *sc) | 128 | mgs_srvconf_rec * sc) |
124 | { | 129 | { |
125 | apr_status_t rv = APR_SUCCESS; | 130 | apr_status_t rv = APR_SUCCESS; |
126 | int thread_limit = 0; | 131 | int thread_limit = 0; |
127 | int nservers = 0; | 132 | int nservers = 0; |
128 | char* cache_config; | 133 | char *cache_config; |
129 | char* split; | 134 | char *split; |
130 | char* tok; | 135 | char *tok; |
131 | 136 | ||
132 | ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); | 137 | ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); |
133 | 138 | ||
134 | /* Find all the servers in the first run to get a total count */ | 139 | /* Find all the servers in the first run to get a total count */ |
135 | cache_config = apr_pstrdup(p, sc->cache_config); | 140 | cache_config = apr_pstrdup(p, sc->cache_config); |
136 | split = apr_strtok(cache_config, " ", &tok); | 141 | split = apr_strtok(cache_config, " ", &tok); |
137 | while (split) { | 142 | while (split) { |
138 | nservers++; | 143 | nservers++; |
139 | split = apr_strtok(NULL," ", &tok); | 144 | split = apr_strtok(NULL, " ", &tok); |
140 | } | 145 | } |
141 | 146 | ||
142 | rv = apr_memcache_create(p, nservers, 0, &mc); | 147 | rv = apr_memcache_create(p, nservers, 0, &mc); |
143 | if (rv != APR_SUCCESS) { | 148 | if (rv != APR_SUCCESS) { |
144 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 149 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
145 | "[gnutls_cache] Failed to create Memcache Object of '%d' size.", | 150 | "[gnutls_cache] Failed to create Memcache Object of '%d' size.", |
146 | nservers); | 151 | nservers); |
147 | return rv; | 152 | return rv; |
148 | } | 153 | } |
149 | 154 | ||
150 | /* Now add each server to the memcache */ | 155 | /* Now add each server to the memcache */ |
151 | cache_config = apr_pstrdup(p, sc->cache_config); | 156 | cache_config = apr_pstrdup(p, sc->cache_config); |
152 | split = apr_strtok(cache_config, " ", &tok); | 157 | split = apr_strtok(cache_config, " ", &tok); |
153 | while (split) { | 158 | while (split) { |
154 | apr_memcache_server_t* st; | 159 | apr_memcache_server_t *st; |
155 | char* host_str; | 160 | char *host_str; |
156 | char* scope_id; | 161 | char *scope_id; |
157 | apr_port_t port; | 162 | apr_port_t port; |
158 | 163 | ||
159 | rv = apr_parse_addr_port(&host_str, &scope_id, &port, split, p); | 164 | rv = apr_parse_addr_port(&host_str, &scope_id, &port, |
160 | if (rv != APR_SUCCESS) { | 165 | split, p); |
161 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 166 | if (rv != APR_SUCCESS) { |
162 | "[gnutls_cache] Failed to Parse Server: '%s'", split); | 167 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
163 | return rv; | 168 | "[gnutls_cache] Failed to Parse Server: '%s'", |
164 | } | 169 | split); |
165 | 170 | return rv; | |
166 | if (host_str == NULL) { | 171 | } |
167 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 172 | |
168 | "[gnutls_cache] Failed to Parse Server, " | 173 | if (host_str == NULL) { |
169 | "no hostname specified: '%s'", split); | 174 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
170 | return rv; | 175 | "[gnutls_cache] Failed to Parse Server, " |
171 | } | 176 | "no hostname specified: '%s'", split); |
172 | 177 | return rv; | |
173 | if (port == 0) { | 178 | } |
174 | port = 11211; /* default port */ | 179 | |
175 | } | 180 | if (port == 0) { |
176 | 181 | port = 11211; /* default port */ | |
177 | /* Should Max Conns be (thread_limit / nservers) ? */ | 182 | } |
178 | rv = apr_memcache_server_create(p, | 183 | |
179 | host_str, port, | 184 | /* Should Max Conns be (thread_limit / nservers) ? */ |
180 | 0, | 185 | rv = apr_memcache_server_create(p, |
181 | 1, | 186 | host_str, port, |
182 | thread_limit, | 187 | 0, |
183 | 600, | 188 | 1, thread_limit, 600, &st); |
184 | &st); | 189 | if (rv != APR_SUCCESS) { |
185 | if (rv != APR_SUCCESS) { | 190 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
186 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 191 | "[gnutls_cache] Failed to Create Server: %s:%d", |
187 | "[gnutls_cache] Failed to Create Server: %s:%d", | 192 | host_str, port); |
188 | host_str, port); | 193 | return rv; |
189 | return rv; | 194 | } |
190 | } | 195 | |
191 | 196 | rv = apr_memcache_add_server(mc, st); | |
192 | rv = apr_memcache_add_server(mc, st); | 197 | if (rv != APR_SUCCESS) { |
193 | if (rv != APR_SUCCESS) { | 198 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, |
194 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, | 199 | "[gnutls_cache] Failed to Add Server: %s:%d", |
195 | "[gnutls_cache] Failed to Add Server: %s:%d", | 200 | host_str, port); |
196 | host_str, port); | 201 | return rv; |
197 | return rv; | 202 | } |
198 | } | 203 | |
199 | 204 | split = apr_strtok(NULL, " ", &tok); | |
200 | split = apr_strtok(NULL," ", &tok); | 205 | } |
201 | } | 206 | return rv; |
202 | return rv; | ||
203 | } | 207 | } |
204 | 208 | ||
205 | static int mc_cache_store(void* baton, gnutls_datum_t key, | 209 | static int mc_cache_store(void *baton, gnutls_datum_t key, |
206 | gnutls_datum_t data) | 210 | gnutls_datum_t data) |
207 | { | 211 | { |
208 | apr_status_t rv = APR_SUCCESS; | 212 | apr_status_t rv = APR_SUCCESS; |
209 | mgs_handle_t *ctxt = baton; | 213 | mgs_handle_t *ctxt = baton; |
210 | char* strkey = NULL; | 214 | char *strkey = NULL; |
211 | apr_uint32_t timeout; | 215 | apr_uint32_t timeout; |
212 | 216 | ||
213 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); | 217 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); |
214 | if(!strkey) | 218 | if (!strkey) |
215 | return -1; | 219 | return -1; |
216 | 220 | ||
217 | timeout = apr_time_sec(ctxt->sc->cache_timeout); | 221 | timeout = apr_time_sec(ctxt->sc->cache_timeout); |
218 | 222 | ||
219 | rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, 0); | 223 | rv = apr_memcache_set(mc, strkey, data.data, data.size, timeout, |
224 | 0); | ||
220 | 225 | ||
221 | if (rv != APR_SUCCESS) { | 226 | if (rv != APR_SUCCESS) { |
222 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, | 227 | ap_log_error(APLOG_MARK, APLOG_CRIT, rv, |
223 | ctxt->c->base_server, | 228 | ctxt->c->base_server, |
224 | "[gnutls_cache] error setting key '%s' " | 229 | "[gnutls_cache] error setting key '%s' " |
225 | "with %d bytes of data", strkey, data.size); | 230 | "with %d bytes of data", strkey, data.size); |
226 | return -1; | 231 | return -1; |
227 | } | 232 | } |
228 | 233 | ||
229 | return 0; | 234 | return 0; |
230 | } | 235 | } |
231 | 236 | ||
232 | static gnutls_datum_t mc_cache_fetch(void* baton, gnutls_datum_t key) | 237 | static gnutls_datum_t mc_cache_fetch(void *baton, gnutls_datum_t key) |
233 | { | 238 | { |
234 | apr_status_t rv = APR_SUCCESS; | 239 | apr_status_t rv = APR_SUCCESS; |
235 | mgs_handle_t *ctxt = baton; | 240 | mgs_handle_t *ctxt = baton; |
236 | char* strkey = NULL; | 241 | char *strkey = NULL; |
237 | char* value; | 242 | char *value; |
238 | apr_size_t value_len; | 243 | apr_size_t value_len; |
239 | gnutls_datum_t data = { NULL, 0 }; | 244 | gnutls_datum_t data = { NULL, 0 }; |
240 | 245 | ||
241 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); | 246 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); |
242 | if (!strkey) { | 247 | if (!strkey) { |
243 | return data; | 248 | return data; |
244 | } | 249 | } |
245 | 250 | ||
246 | rv = apr_memcache_getp(mc, ctxt->c->pool, strkey, | 251 | rv = apr_memcache_getp(mc, ctxt->c->pool, strkey, |
247 | &value, &value_len, NULL); | 252 | &value, &value_len, NULL); |
248 | 253 | ||
249 | if (rv != APR_SUCCESS) { | 254 | if (rv != APR_SUCCESS) { |
250 | #if MOD_GNUTLS_DEBUG | 255 | #if MOD_GNUTLS_DEBUG |
251 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 256 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
252 | ctxt->c->base_server, | 257 | ctxt->c->base_server, |
253 | "[gnutls_cache] error fetching key '%s' ", | 258 | "[gnutls_cache] error fetching key '%s' ", |
254 | strkey); | 259 | strkey); |
255 | #endif | 260 | #endif |
256 | data.size = 0; | 261 | data.size = 0; |
257 | data.data = NULL; | 262 | data.data = NULL; |
258 | return data; | 263 | return data; |
259 | } | 264 | } |
260 | 265 | ||
261 | /* TODO: Eliminate this memcpy. gnutls-- */ | 266 | /* TODO: Eliminate this memcpy. gnutls-- */ |
262 | data.data = gnutls_malloc(value_len); | 267 | data.data = gnutls_malloc(value_len); |
263 | if (data.data == NULL) | 268 | if (data.data == NULL) |
264 | return data; | 269 | return data; |
265 | 270 | ||
266 | data.size = value_len; | 271 | data.size = value_len; |
267 | memcpy(data.data, value, value_len); | 272 | memcpy(data.data, value, value_len); |
268 | 273 | ||
269 | return data; | 274 | return data; |
270 | } | 275 | } |
271 | 276 | ||
272 | static int mc_cache_delete(void* baton, gnutls_datum_t key) | 277 | static int mc_cache_delete(void *baton, gnutls_datum_t key) |
273 | { | 278 | { |
274 | apr_status_t rv = APR_SUCCESS; | 279 | apr_status_t rv = APR_SUCCESS; |
275 | mgs_handle_t *ctxt = baton; | 280 | mgs_handle_t *ctxt = baton; |
276 | char* strkey = NULL; | 281 | char *strkey = NULL; |
277 | 282 | ||
278 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); | 283 | strkey = mgs_session_id2mc(ctxt->c, key.data, key.size); |
279 | if(!strkey) | 284 | if (!strkey) |
280 | return -1; | 285 | return -1; |
281 | 286 | ||
282 | rv = apr_memcache_delete(mc, strkey, 0); | 287 | rv = apr_memcache_delete(mc, strkey, 0); |
283 | 288 | ||
284 | if (rv != APR_SUCCESS) { | 289 | if (rv != APR_SUCCESS) { |
285 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 290 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
286 | ctxt->c->base_server, | 291 | ctxt->c->base_server, |
287 | "[gnutls_cache] error deleting key '%s' ", | 292 | "[gnutls_cache] error deleting key '%s' ", |
288 | strkey); | 293 | strkey); |
289 | return -1; | 294 | return -1; |
290 | } | 295 | } |
291 | 296 | ||
292 | return 0; | 297 | return 0; |
293 | } | 298 | } |
294 | 299 | ||
295 | #endif /* have_apr_memcache */ | 300 | #endif /* have_apr_memcache */ |
296 | 301 | ||
297 | const char* db_type(mgs_srvconf_rec * sc) | 302 | const char *db_type(mgs_srvconf_rec * sc) |
298 | { | 303 | { |
299 | if (sc->cache_type == mgs_cache_gdbm) | 304 | if (sc->cache_type == mgs_cache_gdbm) |
300 | return "gdbm"; | 305 | return "gdbm"; |
301 | else | 306 | else |
302 | return "db"; | 307 | return "db"; |
303 | } | 308 | } |
304 | 309 | ||
305 | #define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) | 310 | #define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD ) |
306 | 311 | ||
307 | static void dbm_cache_expire(mgs_handle_t *ctxt) | 312 | static void dbm_cache_expire(mgs_handle_t * ctxt) |
308 | { | 313 | { |
309 | apr_status_t rv; | 314 | apr_status_t rv; |
310 | apr_dbm_t *dbm; | 315 | apr_dbm_t *dbm; |
311 | apr_datum_t dbmkey; | 316 | apr_datum_t dbmkey; |
312 | apr_datum_t dbmval; | 317 | apr_datum_t dbmval; |
313 | apr_time_t now; | 318 | apr_time_t now; |
314 | apr_time_t dtime; | 319 | apr_time_t dtime; |
315 | apr_pool_t* spool; | 320 | apr_pool_t *spool; |
316 | int total, deleted; | 321 | int total, deleted; |
317 | 322 | ||
318 | now = apr_time_now(); | 323 | now = apr_time_now(); |
319 | 324 | ||
320 | if (now - ctxt->sc->last_cache_check < (ctxt->sc->cache_timeout)/2) | 325 | if (now - ctxt->sc->last_cache_check < |
321 | return; | 326 | (ctxt->sc->cache_timeout) / 2) |
322 | 327 | return; | |
323 | ctxt->sc->last_cache_check = now; | 328 | |
324 | 329 | ctxt->sc->last_cache_check = now; | |
325 | apr_pool_create(&spool, ctxt->c->pool); | 330 | |
326 | 331 | apr_pool_create(&spool, ctxt->c->pool); | |
327 | total = 0; | 332 | |
328 | deleted = 0; | 333 | total = 0; |
329 | 334 | deleted = 0; | |
330 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), ctxt->sc->cache_config, APR_DBM_RWCREATE, | 335 | |
331 | SSL_DBM_FILE_MODE, spool); | 336 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), |
332 | if (rv != APR_SUCCESS) { | 337 | ctxt->sc->cache_config, APR_DBM_RWCREATE, |
333 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 338 | SSL_DBM_FILE_MODE, spool); |
334 | ctxt->c->base_server, | 339 | if (rv != APR_SUCCESS) { |
335 | "[gnutls_cache] error opening cache searcher '%s'", | 340 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
336 | ctxt->sc->cache_config); | 341 | ctxt->c->base_server, |
337 | apr_pool_destroy(spool); | 342 | "[gnutls_cache] error opening cache searcher '%s'", |
338 | return; | 343 | ctxt->sc->cache_config); |
339 | } | 344 | apr_pool_destroy(spool); |
340 | 345 | return; | |
341 | apr_dbm_firstkey(dbm, &dbmkey); | 346 | } |
342 | while (dbmkey.dptr != NULL) { | 347 | |
343 | apr_dbm_fetch(dbm, dbmkey, &dbmval); | 348 | apr_dbm_firstkey(dbm, &dbmkey); |
344 | if (dbmval.dptr != NULL && dbmval.dsize >= sizeof(apr_time_t)) { | 349 | while (dbmkey.dptr != NULL) { |
345 | memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t)); | 350 | apr_dbm_fetch(dbm, dbmkey, &dbmval); |
346 | 351 | if (dbmval.dptr != NULL | |
347 | if (now >= dtime) { | 352 | && dbmval.dsize >= sizeof(apr_time_t)) { |
348 | apr_dbm_delete(dbm, dbmkey); | 353 | memcpy(&dtime, dbmval.dptr, sizeof(apr_time_t)); |
349 | deleted++; | 354 | |
350 | } | 355 | if (now >= dtime) { |
351 | apr_dbm_freedatum( dbm, dbmval); | 356 | apr_dbm_delete(dbm, dbmkey); |
352 | } else { | 357 | deleted++; |
353 | apr_dbm_delete(dbm, dbmkey); | 358 | } |
354 | deleted++; | 359 | apr_dbm_freedatum(dbm, dbmval); |
355 | } | 360 | } else { |
356 | total++; | 361 | apr_dbm_delete(dbm, dbmkey); |
357 | apr_dbm_nextkey(dbm, &dbmkey); | 362 | deleted++; |
358 | } | 363 | } |
359 | apr_dbm_close(dbm); | 364 | total++; |
360 | 365 | apr_dbm_nextkey(dbm, &dbmkey); | |
361 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 366 | } |
362 | ctxt->c->base_server, | 367 | apr_dbm_close(dbm); |
363 | "[gnutls_cache] Cleaned up cache '%s'. Deleted %d and left %d", | 368 | |
364 | ctxt->sc->cache_config, deleted, total-deleted); | 369 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
365 | 370 | ctxt->c->base_server, | |
366 | apr_pool_destroy(spool); | 371 | "[gnutls_cache] Cleaned up cache '%s'. Deleted %d and left %d", |
367 | 372 | ctxt->sc->cache_config, deleted, total - deleted); | |
368 | return; | 373 | |
374 | apr_pool_destroy(spool); | ||
375 | |||
376 | return; | ||
369 | } | 377 | } |
370 | 378 | ||
371 | static gnutls_datum_t dbm_cache_fetch(void* baton, gnutls_datum_t key) | 379 | static gnutls_datum_t dbm_cache_fetch(void *baton, gnutls_datum_t key) |
372 | { | 380 | { |
373 | gnutls_datum_t data = { NULL, 0 }; | 381 | gnutls_datum_t data = { NULL, 0 }; |
374 | apr_dbm_t *dbm; | 382 | apr_dbm_t *dbm; |
375 | apr_datum_t dbmkey; | 383 | apr_datum_t dbmkey; |
376 | apr_datum_t dbmval; | 384 | apr_datum_t dbmval; |
377 | mgs_handle_t *ctxt = baton; | 385 | mgs_handle_t *ctxt = baton; |
378 | apr_status_t rv; | 386 | apr_status_t rv; |
379 | 387 | ||
380 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) | 388 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) |
381 | return data; | 389 | return data; |
382 | 390 | ||
383 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), ctxt->sc->cache_config, | 391 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), |
384 | APR_DBM_READONLY, SSL_DBM_FILE_MODE, ctxt->c->pool); | 392 | ctxt->sc->cache_config, APR_DBM_READONLY, |
385 | if (rv != APR_SUCCESS) { | 393 | SSL_DBM_FILE_MODE, ctxt->c->pool); |
386 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 394 | if (rv != APR_SUCCESS) { |
387 | ctxt->c->base_server, | 395 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
388 | "[gnutls_cache] error opening cache '%s'", | 396 | ctxt->c->base_server, |
389 | ctxt->sc->cache_config); | 397 | "[gnutls_cache] error opening cache '%s'", |
390 | return data; | 398 | ctxt->sc->cache_config); |
391 | } | 399 | return data; |
392 | 400 | } | |
393 | rv = apr_dbm_fetch(dbm, dbmkey, &dbmval); | 401 | |
394 | 402 | rv = apr_dbm_fetch(dbm, dbmkey, &dbmval); | |
395 | if (rv != APR_SUCCESS) { | 403 | |
396 | apr_dbm_close(dbm); | 404 | if (rv != APR_SUCCESS) { |
397 | return data; | 405 | apr_dbm_close(dbm); |
398 | } | 406 | return data; |
399 | 407 | } | |
400 | if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(apr_time_t)) { | 408 | |
401 | apr_dbm_freedatum( dbm, dbmval); | 409 | if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(apr_time_t)) { |
402 | apr_dbm_close(dbm); | 410 | apr_dbm_freedatum(dbm, dbmval); |
403 | return data; | 411 | apr_dbm_close(dbm); |
404 | } | 412 | return data; |
405 | 413 | } | |
406 | data.size = dbmval.dsize - sizeof(apr_time_t); | 414 | |
407 | 415 | data.size = dbmval.dsize - sizeof(apr_time_t); | |
408 | data.data = gnutls_malloc(data.size); | 416 | |
409 | if (data.data == NULL) { | 417 | data.data = gnutls_malloc(data.size); |
410 | apr_dbm_freedatum( dbm, dbmval); | 418 | if (data.data == NULL) { |
411 | apr_dbm_close(dbm); | 419 | apr_dbm_freedatum(dbm, dbmval); |
412 | return data; | 420 | apr_dbm_close(dbm); |
413 | } | 421 | return data; |
414 | 422 | } | |
415 | memcpy(data.data, dbmval.dptr+sizeof(apr_time_t), data.size); | 423 | |
416 | 424 | memcpy(data.data, dbmval.dptr + sizeof(apr_time_t), data.size); | |
417 | apr_dbm_freedatum( dbm, dbmval); | 425 | |
418 | apr_dbm_close(dbm); | 426 | apr_dbm_freedatum(dbm, dbmval); |
419 | 427 | apr_dbm_close(dbm); | |
420 | return data; | 428 | |
429 | return data; | ||
421 | } | 430 | } |
422 | 431 | ||
423 | static int dbm_cache_store(void* baton, gnutls_datum_t key, | 432 | static int dbm_cache_store(void *baton, gnutls_datum_t key, |
424 | gnutls_datum_t data) | 433 | gnutls_datum_t data) |
425 | { | 434 | { |
426 | apr_dbm_t *dbm; | 435 | apr_dbm_t *dbm; |
427 | apr_datum_t dbmkey; | 436 | apr_datum_t dbmkey; |
428 | apr_datum_t dbmval; | 437 | apr_datum_t dbmval; |
429 | mgs_handle_t *ctxt = baton; | 438 | mgs_handle_t *ctxt = baton; |
430 | apr_status_t rv; | 439 | apr_status_t rv; |
431 | apr_time_t expiry; | 440 | apr_time_t expiry; |
432 | apr_pool_t* spool; | 441 | apr_pool_t *spool; |
433 | 442 | ||
434 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) | 443 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) |
435 | return -1; | 444 | return -1; |
436 | 445 | ||
437 | /* we expire dbm only on every store | 446 | /* we expire dbm only on every store |
438 | */ | 447 | */ |
439 | dbm_cache_expire(ctxt); | 448 | dbm_cache_expire(ctxt); |
440 | 449 | ||
441 | apr_pool_create(&spool, ctxt->c->pool); | 450 | apr_pool_create(&spool, ctxt->c->pool); |
442 | 451 | ||
443 | /* create DBM value */ | 452 | /* create DBM value */ |
444 | dbmval.dsize = data.size + sizeof(apr_time_t); | 453 | dbmval.dsize = data.size + sizeof(apr_time_t); |
445 | dbmval.dptr = (char *)apr_palloc(spool, dbmval.dsize); | 454 | dbmval.dptr = (char *) apr_palloc(spool, dbmval.dsize); |
446 | 455 | ||
447 | expiry = apr_time_now() + ctxt->sc->cache_timeout; | 456 | expiry = apr_time_now() + ctxt->sc->cache_timeout; |
448 | 457 | ||
449 | memcpy((char *)dbmval.dptr, &expiry, sizeof(apr_time_t)); | 458 | memcpy((char *) dbmval.dptr, &expiry, sizeof(apr_time_t)); |
450 | memcpy((char *)dbmval.dptr+sizeof(apr_time_t), | 459 | memcpy((char *) dbmval.dptr + sizeof(apr_time_t), |
451 | data.data, data.size); | 460 | data.data, data.size); |
452 | 461 | ||
453 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), ctxt->sc->cache_config, | 462 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), |
454 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 463 | ctxt->sc->cache_config, APR_DBM_RWCREATE, |
455 | if (rv != APR_SUCCESS) { | 464 | SSL_DBM_FILE_MODE, ctxt->c->pool); |
456 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 465 | if (rv != APR_SUCCESS) { |
457 | ctxt->c->base_server, | 466 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
458 | "[gnutls_cache] error opening cache '%s'", | 467 | ctxt->c->base_server, |
459 | ctxt->sc->cache_config); | 468 | "[gnutls_cache] error opening cache '%s'", |
460 | apr_pool_destroy(spool); | 469 | ctxt->sc->cache_config); |
461 | return -1; | 470 | apr_pool_destroy(spool); |
462 | } | 471 | return -1; |
463 | 472 | } | |
464 | rv = apr_dbm_store(dbm, dbmkey, dbmval); | 473 | |
465 | 474 | rv = apr_dbm_store(dbm, dbmkey, dbmval); | |
466 | if (rv != APR_SUCCESS) { | 475 | |
467 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, | 476 | if (rv != APR_SUCCESS) { |
468 | ctxt->c->base_server, | 477 | ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, |
469 | "[gnutls_cache] error storing in cache '%s'", | 478 | ctxt->c->base_server, |
470 | ctxt->sc->cache_config); | 479 | "[gnutls_cache] error storing in cache '%s'", |
471 | apr_dbm_close(dbm); | 480 | ctxt->sc->cache_config); |
472 | apr_pool_destroy(spool); | 481 | apr_dbm_close(dbm); |
473 | return -1; | 482 | apr_pool_destroy(spool); |
474 | } | 483 | return -1; |
475 | 484 | } | |
476 | apr_dbm_close(dbm); | 485 | |
477 | 486 | apr_dbm_close(dbm); | |
478 | apr_pool_destroy(spool); | 487 | |
479 | 488 | apr_pool_destroy(spool); | |
480 | return 0; | 489 | |
490 | return 0; | ||
481 | } | 491 | } |
482 | 492 | ||
483 | static int dbm_cache_delete(void* baton, gnutls_datum_t key) | 493 | static int dbm_cache_delete(void *baton, gnutls_datum_t key) |
484 | { | 494 | { |
485 | apr_dbm_t *dbm; | 495 | apr_dbm_t *dbm; |
486 | apr_datum_t dbmkey; | 496 | apr_datum_t dbmkey; |
487 | mgs_handle_t *ctxt = baton; | 497 | mgs_handle_t *ctxt = baton; |
488 | apr_status_t rv; | 498 | apr_status_t rv; |
489 | 499 | ||
490 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) | 500 | if (mgs_session_id2dbm(ctxt->c, key.data, key.size, &dbmkey) < 0) |
491 | return -1; | 501 | return -1; |
492 | 502 | ||
493 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), ctxt->sc->cache_config, | 503 | rv = apr_dbm_open_ex(&dbm, db_type(ctxt->sc), |
494 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, ctxt->c->pool); | 504 | ctxt->sc->cache_config, APR_DBM_RWCREATE, |
495 | if (rv != APR_SUCCESS) { | 505 | SSL_DBM_FILE_MODE, ctxt->c->pool); |
496 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 506 | if (rv != APR_SUCCESS) { |
497 | ctxt->c->base_server, | 507 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
498 | "[gnutls_cache] error opening cache '%s'", | 508 | ctxt->c->base_server, |
499 | ctxt->sc->cache_config); | 509 | "[gnutls_cache] error opening cache '%s'", |
500 | return -1; | 510 | ctxt->sc->cache_config); |
501 | } | 511 | return -1; |
502 | 512 | } | |
503 | rv = apr_dbm_delete(dbm, dbmkey); | 513 | |
504 | 514 | rv = apr_dbm_delete(dbm, dbmkey); | |
505 | if (rv != APR_SUCCESS) { | 515 | |
506 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, | 516 | if (rv != APR_SUCCESS) { |
507 | ctxt->c->base_server, | 517 | ap_log_error(APLOG_MARK, APLOG_NOTICE, rv, |
508 | "[gnutls_cache] error deleting from cache '%s'", | 518 | ctxt->c->base_server, |
509 | ctxt->sc->cache_config); | 519 | "[gnutls_cache] error deleting from cache '%s'", |
510 | apr_dbm_close(dbm); | 520 | ctxt->sc->cache_config); |
511 | return -1; | 521 | apr_dbm_close(dbm); |
512 | } | 522 | return -1; |
513 | 523 | } | |
514 | apr_dbm_close(dbm); | 524 | |
515 | 525 | apr_dbm_close(dbm); | |
516 | return 0; | 526 | |
527 | return 0; | ||
517 | } | 528 | } |
518 | 529 | ||
519 | static int dbm_cache_post_config(apr_pool_t *p, server_rec *s, | 530 | static int dbm_cache_post_config(apr_pool_t * p, server_rec * s, |
520 | mgs_srvconf_rec *sc) | 531 | mgs_srvconf_rec * sc) |
521 | { | 532 | { |
522 | apr_status_t rv; | 533 | apr_status_t rv; |
523 | apr_dbm_t *dbm; | 534 | apr_dbm_t *dbm; |
524 | const char* path1; | 535 | const char *path1; |
525 | const char* path2; | 536 | const char *path2; |
526 | 537 | ||
527 | rv = apr_dbm_open_ex(&dbm, db_type(sc), sc->cache_config, APR_DBM_RWCREATE, | 538 | rv = apr_dbm_open_ex(&dbm, db_type(sc), sc->cache_config, |
528 | SSL_DBM_FILE_MODE, p); | 539 | APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, p); |
529 | 540 | ||
530 | if (rv != APR_SUCCESS) { | 541 | if (rv != APR_SUCCESS) { |
531 | ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, | 542 | ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, |
532 | "GnuTLS: Cannot create DBM Cache at `%s'", | 543 | "GnuTLS: Cannot create DBM Cache at `%s'", |
533 | sc->cache_config); | 544 | sc->cache_config); |
534 | return rv; | 545 | return rv; |
535 | } | 546 | } |
536 | 547 | ||
537 | apr_dbm_close(dbm); | 548 | apr_dbm_close(dbm); |
538 | 549 | ||
539 | apr_dbm_get_usednames_ex(p, db_type(sc), sc->cache_config, &path1, &path2); | 550 | apr_dbm_get_usednames_ex(p, db_type(sc), sc->cache_config, &path1, |
551 | &path2); | ||
540 | 552 | ||
541 | /* The Following Code takes logic directly from mod_ssl's DBM Cache */ | 553 | /* The Following Code takes logic directly from mod_ssl's DBM Cache */ |
542 | #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) | 554 | #if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) |
543 | /* Running as Root */ | 555 | /* Running as Root */ |
544 | if (path1 && geteuid() == 0) { | 556 | if (path1 && geteuid() == 0) { |
545 | chown(path1, ap_unixd_config.user_id, -1); | 557 | chown(path1, ap_unixd_config.user_id, -1); |
546 | if (path2 != NULL) { | 558 | if (path2 != NULL) { |
547 | chown(path2, ap_unixd_config.user_id, -1); | 559 | chown(path2, ap_unixd_config.user_id, -1); |
548 | } | 560 | } |
549 | } | 561 | } |
550 | #endif | 562 | #endif |
551 | 563 | ||
552 | return rv; | 564 | return rv; |
553 | } | 565 | } |
554 | 566 | ||
555 | int mgs_cache_post_config(apr_pool_t *p, server_rec *s, | 567 | int mgs_cache_post_config(apr_pool_t * p, server_rec * s, |
556 | mgs_srvconf_rec *sc) | 568 | mgs_srvconf_rec * sc) |
557 | { | 569 | { |
558 | if (sc->cache_type == mgs_cache_dbm || sc->cache_type == mgs_cache_gdbm) { | 570 | if (sc->cache_type == mgs_cache_dbm |
559 | return dbm_cache_post_config(p, s, sc); | 571 | || sc->cache_type == mgs_cache_gdbm) { |
560 | } | 572 | return dbm_cache_post_config(p, s, sc); |
561 | return 0; | 573 | } |
574 | return 0; | ||
562 | } | 575 | } |
563 | 576 | ||
564 | int mgs_cache_child_init(apr_pool_t *p, server_rec *s, | 577 | int mgs_cache_child_init(apr_pool_t * p, server_rec * s, |
565 | mgs_srvconf_rec *sc) | 578 | mgs_srvconf_rec * sc) |
566 | { | 579 | { |
567 | if (sc->cache_type == mgs_cache_dbm || sc->cache_type == mgs_cache_gdbm) { | 580 | if (sc->cache_type == mgs_cache_dbm |
568 | return 0; | 581 | || sc->cache_type == mgs_cache_gdbm) { |
569 | } | 582 | return 0; |
583 | } | ||
570 | #if HAVE_APR_MEMCACHE | 584 | #if HAVE_APR_MEMCACHE |
571 | else if (sc->cache_type == mgs_cache_memcache) { | 585 | else if (sc->cache_type == mgs_cache_memcache) { |
572 | return mc_cache_child_init(p, s, sc); | 586 | return mc_cache_child_init(p, s, sc); |
573 | } | 587 | } |
574 | #endif | 588 | #endif |
575 | return 0; | 589 | return 0; |
576 | } | 590 | } |
577 | 591 | ||
578 | #include <assert.h> | 592 | #include <assert.h> |
579 | 593 | ||
580 | int mgs_cache_session_init(mgs_handle_t *ctxt) | 594 | int mgs_cache_session_init(mgs_handle_t * ctxt) |
581 | { | 595 | { |
582 | if (ctxt->sc->cache_type == mgs_cache_dbm || ctxt->sc->cache_type == mgs_cache_gdbm) { | 596 | if (ctxt->sc->cache_type == mgs_cache_dbm |
583 | gnutls_db_set_retrieve_function(ctxt->session, dbm_cache_fetch); | 597 | || ctxt->sc->cache_type == mgs_cache_gdbm) { |
584 | gnutls_db_set_remove_function(ctxt->session, dbm_cache_delete); | 598 | gnutls_db_set_retrieve_function(ctxt->session, |
585 | gnutls_db_set_store_function(ctxt->session, dbm_cache_store); | 599 | dbm_cache_fetch); |
586 | gnutls_db_set_ptr(ctxt->session, ctxt); | 600 | gnutls_db_set_remove_function(ctxt->session, |
587 | } | 601 | dbm_cache_delete); |
602 | gnutls_db_set_store_function(ctxt->session, | ||
603 | dbm_cache_store); | ||
604 | gnutls_db_set_ptr(ctxt->session, ctxt); | ||
605 | } | ||
588 | #if HAVE_APR_MEMCACHE | 606 | #if HAVE_APR_MEMCACHE |
589 | else if (ctxt->sc->cache_type == mgs_cache_memcache) { | 607 | else if (ctxt->sc->cache_type == mgs_cache_memcache) { |
590 | gnutls_db_set_retrieve_function(ctxt->session, mc_cache_fetch); | 608 | gnutls_db_set_retrieve_function(ctxt->session, |
591 | gnutls_db_set_remove_function(ctxt->session, mc_cache_delete); | 609 | mc_cache_fetch); |
592 | gnutls_db_set_store_function(ctxt->session, mc_cache_store); | 610 | gnutls_db_set_remove_function(ctxt->session, |
593 | gnutls_db_set_ptr(ctxt->session, ctxt); | 611 | mc_cache_delete); |
594 | } | 612 | gnutls_db_set_store_function(ctxt->session, |
613 | mc_cache_store); | ||
614 | gnutls_db_set_ptr(ctxt->session, ctxt); | ||
615 | } | ||
595 | #endif | 616 | #endif |
596 | 617 | ||
597 | return 0; | 618 | return 0; |
598 | } | 619 | } |
diff --git a/src/gnutls_config.c b/src/gnutls_config.c index ff8ec33..fc3e166 100644 --- a/src/gnutls_config.c +++ b/src/gnutls_config.c | |||
@@ -21,284 +21,308 @@ | |||
21 | static int load_datum_from_file(apr_pool_t * pool, | 21 | static int load_datum_from_file(apr_pool_t * pool, |
22 | const char *file, gnutls_datum_t * data) | 22 | const char *file, gnutls_datum_t * data) |
23 | { | 23 | { |
24 | apr_file_t *fp; | 24 | apr_file_t *fp; |
25 | apr_finfo_t finfo; | 25 | apr_finfo_t finfo; |
26 | apr_status_t rv; | 26 | apr_status_t rv; |
27 | apr_size_t br = 0; | 27 | apr_size_t br = 0; |
28 | 28 | ||
29 | rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, APR_OS_DEFAULT, | 29 | rv = apr_file_open(&fp, file, APR_READ | APR_BINARY, |
30 | pool); | 30 | APR_OS_DEFAULT, pool); |
31 | if (rv != APR_SUCCESS) { | 31 | if (rv != APR_SUCCESS) { |
32 | return rv; | 32 | return rv; |
33 | } | 33 | } |
34 | 34 | ||
35 | rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp); | 35 | rv = apr_file_info_get(&finfo, APR_FINFO_SIZE, fp); |
36 | 36 | ||
37 | if (rv != APR_SUCCESS) { | 37 | if (rv != APR_SUCCESS) { |
38 | return rv; | 38 | return rv; |
39 | } | 39 | } |
40 | 40 | ||
41 | data->data = apr_palloc(pool, finfo.size + 1); | 41 | data->data = apr_palloc(pool, finfo.size + 1); |
42 | rv = apr_file_read_full(fp, data->data, finfo.size, &br); | 42 | rv = apr_file_read_full(fp, data->data, finfo.size, &br); |
43 | 43 | ||
44 | if (rv != APR_SUCCESS) { | 44 | if (rv != APR_SUCCESS) { |
45 | return rv; | 45 | return rv; |
46 | } | 46 | } |
47 | apr_file_close(fp); | 47 | apr_file_close(fp); |
48 | 48 | ||
49 | data->data[br] = '\0'; | 49 | data->data[br] = '\0'; |
50 | data->size = br; | 50 | data->size = br; |
51 | 51 | ||
52 | return 0; | 52 | return 0; |
53 | } | 53 | } |
54 | 54 | ||
55 | const char *mgs_set_dh_file(cmd_parms * parms, void *dummy, | 55 | const char *mgs_set_dh_file(cmd_parms * parms, void *dummy, |
56 | const char *arg) | 56 | const char *arg) |
57 | { | 57 | { |
58 | int ret; | 58 | int ret; |
59 | gnutls_datum_t data; | 59 | gnutls_datum_t data; |
60 | const char *file; | 60 | const char *file; |
61 | apr_pool_t *spool; | 61 | apr_pool_t *spool; |
62 | mgs_srvconf_rec *sc = | 62 | mgs_srvconf_rec *sc = |
63 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 63 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
64 | module_config, | 64 | module_config, |
65 | &gnutls_module); | 65 | &gnutls_module); |
66 | 66 | ||
67 | apr_pool_create(&spool, parms->pool); | 67 | apr_pool_create(&spool, parms->pool); |
68 | 68 | ||
69 | file = ap_server_root_relative(spool, arg); | 69 | file = ap_server_root_relative(spool, arg); |
70 | 70 | ||
71 | if (load_datum_from_file(spool, file, &data) != 0) { | 71 | if (load_datum_from_file(spool, file, &data) != 0) { |
72 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " | 72 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " |
73 | "DH params '%s'", file); | 73 | "DH params '%s'", file); |
74 | } | 74 | } |
75 | 75 | ||
76 | ret = gnutls_dh_params_init(&sc->dh_params); | 76 | ret = gnutls_dh_params_init(&sc->dh_params); |
77 | if (ret < 0) { | 77 | if (ret < 0) { |
78 | return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" | 78 | return apr_psprintf(parms->pool, |
79 | ": (%d) %s", ret, gnutls_strerror(ret)); | 79 | "GnuTLS: Failed to initialize" |
80 | } | 80 | ": (%d) %s", ret, |
81 | 81 | gnutls_strerror(ret)); | |
82 | ret = | 82 | } |
83 | gnutls_dh_params_import_pkcs3(sc->dh_params, &data, GNUTLS_X509_FMT_PEM); | 83 | |
84 | if (ret < 0) { | 84 | ret = |
85 | return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " | 85 | gnutls_dh_params_import_pkcs3(sc->dh_params, &data, |
86 | "DH params '%s': (%d) %s", file, ret, | 86 | GNUTLS_X509_FMT_PEM); |
87 | gnutls_strerror(ret)); | 87 | if (ret < 0) { |
88 | } | 88 | return apr_psprintf(parms->pool, |
89 | 89 | "GnuTLS: Failed to Import " | |
90 | apr_pool_destroy(spool); | 90 | "DH params '%s': (%d) %s", file, ret, |
91 | 91 | gnutls_strerror(ret)); | |
92 | return NULL; | 92 | } |
93 | |||
94 | apr_pool_destroy(spool); | ||
95 | |||
96 | return NULL; | ||
93 | } | 97 | } |
94 | 98 | ||
95 | const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy, | 99 | const char *mgs_set_rsa_export_file(cmd_parms * parms, void *dummy, |
96 | const char *arg) | 100 | const char *arg) |
97 | { | 101 | { |
98 | int ret; | 102 | int ret; |
99 | gnutls_datum_t data; | 103 | gnutls_datum_t data; |
100 | const char *file; | 104 | const char *file; |
101 | apr_pool_t *spool; | 105 | apr_pool_t *spool; |
102 | mgs_srvconf_rec *sc = | 106 | mgs_srvconf_rec *sc = |
103 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 107 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
104 | module_config, | 108 | module_config, |
105 | &gnutls_module); | 109 | &gnutls_module); |
106 | 110 | ||
107 | apr_pool_create(&spool, parms->pool); | 111 | apr_pool_create(&spool, parms->pool); |
108 | 112 | ||
109 | file = ap_server_root_relative(spool, arg); | 113 | file = ap_server_root_relative(spool, arg); |
110 | 114 | ||
111 | if (load_datum_from_file(spool, file, &data) != 0) { | 115 | if (load_datum_from_file(spool, file, &data) != 0) { |
112 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " | 116 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " |
113 | "RSA params '%s'", file); | 117 | "RSA params '%s'", file); |
114 | } | 118 | } |
115 | 119 | ||
116 | ret = gnutls_rsa_params_init(&sc->rsa_params); | 120 | ret = gnutls_rsa_params_init(&sc->rsa_params); |
117 | if (ret < 0) { | 121 | if (ret < 0) { |
118 | return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" | 122 | return apr_psprintf(parms->pool, |
119 | ": (%d) %s", ret, gnutls_strerror(ret)); | 123 | "GnuTLS: Failed to initialize" |
120 | } | 124 | ": (%d) %s", ret, |
121 | 125 | gnutls_strerror(ret)); | |
122 | ret = | 126 | } |
123 | gnutls_rsa_params_import_pkcs1(sc->rsa_params, &data, GNUTLS_X509_FMT_PEM); | 127 | |
124 | if (ret != 0) { | 128 | ret = |
125 | return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " | 129 | gnutls_rsa_params_import_pkcs1(sc->rsa_params, &data, |
126 | "RSA params '%s': (%d) %s", file, ret, | 130 | GNUTLS_X509_FMT_PEM); |
127 | gnutls_strerror(ret)); | 131 | if (ret != 0) { |
128 | } | 132 | return apr_psprintf(parms->pool, |
129 | 133 | "GnuTLS: Failed to Import " | |
130 | apr_pool_destroy(spool); | 134 | "RSA params '%s': (%d) %s", file, ret, |
131 | return NULL; | 135 | gnutls_strerror(ret)); |
136 | } | ||
137 | |||
138 | apr_pool_destroy(spool); | ||
139 | return NULL; | ||
132 | } | 140 | } |
133 | 141 | ||
134 | 142 | ||
135 | const char *mgs_set_cert_file(cmd_parms * parms, void *dummy, | 143 | const char *mgs_set_cert_file(cmd_parms * parms, void *dummy, |
136 | const char *arg) | 144 | const char *arg) |
137 | { | 145 | { |
138 | int ret; | 146 | int ret; |
139 | gnutls_datum_t data; | 147 | gnutls_datum_t data; |
140 | const char *file; | 148 | const char *file; |
141 | apr_pool_t *spool; | 149 | apr_pool_t *spool; |
142 | mgs_srvconf_rec *sc = | 150 | mgs_srvconf_rec *sc = |
143 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 151 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
144 | module_config, | 152 | module_config, |
145 | &gnutls_module); | 153 | &gnutls_module); |
146 | apr_pool_create(&spool, parms->pool); | 154 | apr_pool_create(&spool, parms->pool); |
147 | 155 | ||
148 | file = ap_server_root_relative(spool, arg); | 156 | file = ap_server_root_relative(spool, arg); |
149 | 157 | ||
150 | if (load_datum_from_file(spool, file, &data) != 0) { | 158 | if (load_datum_from_file(spool, file, &data) != 0) { |
151 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " | 159 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " |
152 | "Certificate '%s'", file); | 160 | "Certificate '%s'", file); |
153 | } | 161 | } |
154 | 162 | ||
155 | sc->certs_x509_num = MAX_CHAIN_SIZE; | 163 | sc->certs_x509_num = MAX_CHAIN_SIZE; |
156 | ret = | 164 | ret = |
157 | gnutls_x509_crt_list_import(sc->certs_x509, &sc->certs_x509_num, &data, GNUTLS_X509_FMT_PEM, 0); | 165 | gnutls_x509_crt_list_import(sc->certs_x509, |
158 | if (ret < 0) { | 166 | &sc->certs_x509_num, &data, |
159 | return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " | 167 | GNUTLS_X509_FMT_PEM, 0); |
160 | "Certificate '%s': (%d) %s", file, ret, | 168 | if (ret < 0) { |
161 | gnutls_strerror(ret)); | 169 | return apr_psprintf(parms->pool, |
162 | } | 170 | "GnuTLS: Failed to Import " |
163 | 171 | "Certificate '%s': (%d) %s", file, ret, | |
164 | apr_pool_destroy(spool); | 172 | gnutls_strerror(ret)); |
165 | return NULL; | 173 | } |
174 | |||
175 | apr_pool_destroy(spool); | ||
176 | return NULL; | ||
166 | } | 177 | } |
167 | 178 | ||
168 | const char *mgs_set_key_file(cmd_parms * parms, void *dummy, | 179 | const char *mgs_set_key_file(cmd_parms * parms, void *dummy, |
169 | const char *arg) | 180 | const char *arg) |
170 | { | 181 | { |
171 | int ret; | 182 | int ret; |
172 | gnutls_datum_t data; | 183 | gnutls_datum_t data; |
173 | const char *file; | 184 | const char *file; |
174 | apr_pool_t *spool; | 185 | apr_pool_t *spool; |
175 | mgs_srvconf_rec *sc = | 186 | mgs_srvconf_rec *sc = |
176 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 187 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
177 | module_config, | 188 | module_config, |
178 | &gnutls_module); | 189 | &gnutls_module); |
179 | apr_pool_create(&spool, parms->pool); | 190 | apr_pool_create(&spool, parms->pool); |
180 | 191 | ||
181 | file = ap_server_root_relative(spool, arg); | 192 | file = ap_server_root_relative(spool, arg); |
182 | 193 | ||
183 | if (load_datum_from_file(spool, file, &data) != 0) { | 194 | if (load_datum_from_file(spool, file, &data) != 0) { |
184 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " | 195 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " |
185 | "Private Key '%s'", file); | 196 | "Private Key '%s'", file); |
186 | } | 197 | } |
187 | 198 | ||
188 | ret = gnutls_x509_privkey_init(&sc->privkey_x509); | 199 | ret = gnutls_x509_privkey_init(&sc->privkey_x509); |
189 | if (ret < 0) { | 200 | if (ret < 0) { |
190 | return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" | 201 | return apr_psprintf(parms->pool, |
191 | ": (%d) %s", ret, gnutls_strerror(ret)); | 202 | "GnuTLS: Failed to initialize" |
192 | } | 203 | ": (%d) %s", ret, |
193 | 204 | gnutls_strerror(ret)); | |
194 | ret = | 205 | } |
195 | gnutls_x509_privkey_import(sc->privkey_x509, &data, | 206 | |
196 | GNUTLS_X509_FMT_PEM); | 207 | ret = |
197 | 208 | gnutls_x509_privkey_import(sc->privkey_x509, &data, | |
198 | if (ret < 0) | 209 | GNUTLS_X509_FMT_PEM); |
199 | ret = gnutls_x509_privkey_import_pkcs8 (sc->privkey_x509, &data, GNUTLS_X509_FMT_PEM, | 210 | |
200 | NULL, GNUTLS_PKCS_PLAIN); | 211 | if (ret < 0) |
201 | 212 | ret = | |
202 | if (ret < 0) { | 213 | gnutls_x509_privkey_import_pkcs8(sc->privkey_x509, |
203 | return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " | 214 | &data, |
204 | "Private Key '%s': (%d) %s", file, ret, | 215 | GNUTLS_X509_FMT_PEM, |
205 | gnutls_strerror(ret)); | 216 | NULL, |
206 | } | 217 | GNUTLS_PKCS_PLAIN); |
207 | apr_pool_destroy(spool); | 218 | |
208 | return NULL; | 219 | if (ret < 0) { |
220 | return apr_psprintf(parms->pool, | ||
221 | "GnuTLS: Failed to Import " | ||
222 | "Private Key '%s': (%d) %s", file, ret, | ||
223 | gnutls_strerror(ret)); | ||
224 | } | ||
225 | apr_pool_destroy(spool); | ||
226 | return NULL; | ||
209 | } | 227 | } |
210 | 228 | ||
211 | const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy, | 229 | const char *mgs_set_pgpcert_file(cmd_parms * parms, void *dummy, |
212 | const char *arg) | 230 | const char *arg) |
213 | { | 231 | { |
214 | int ret; | 232 | int ret; |
215 | gnutls_datum_t data; | 233 | gnutls_datum_t data; |
216 | const char *file; | 234 | const char *file; |
217 | apr_pool_t *spool; | 235 | apr_pool_t *spool; |
218 | mgs_srvconf_rec *sc = | 236 | mgs_srvconf_rec *sc = |
219 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 237 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
220 | module_config, | 238 | module_config, |
221 | &gnutls_module); | 239 | &gnutls_module); |
222 | apr_pool_create(&spool, parms->pool); | 240 | apr_pool_create(&spool, parms->pool); |
223 | 241 | ||
224 | file = ap_server_root_relative(spool, arg); | 242 | file = ap_server_root_relative(spool, arg); |
225 | 243 | ||
226 | if (load_datum_from_file(spool, file, &data) != 0) { | 244 | if (load_datum_from_file(spool, file, &data) != 0) { |
227 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " | 245 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " |
228 | "Certificate '%s'", file); | 246 | "Certificate '%s'", file); |
229 | } | 247 | } |
230 | 248 | ||
231 | ret = gnutls_openpgp_crt_init( &sc->cert_pgp); | 249 | ret = gnutls_openpgp_crt_init(&sc->cert_pgp); |
232 | if (ret < 0) { | 250 | if (ret < 0) { |
233 | return apr_psprintf(parms->pool, "GnuTLS: Failed to Init " | 251 | return apr_psprintf(parms->pool, "GnuTLS: Failed to Init " |
234 | "PGP Certificate: (%d) %s", ret, | 252 | "PGP Certificate: (%d) %s", ret, |
235 | gnutls_strerror(ret)); | 253 | gnutls_strerror(ret)); |
236 | } | 254 | } |
237 | 255 | ||
238 | ret = | 256 | ret = |
239 | gnutls_openpgp_crt_import(sc->cert_pgp, &data, GNUTLS_OPENPGP_FMT_BASE64); | 257 | gnutls_openpgp_crt_import(sc->cert_pgp, &data, |
240 | if (ret < 0) { | 258 | GNUTLS_OPENPGP_FMT_BASE64); |
241 | return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " | 259 | if (ret < 0) { |
242 | "PGP Certificate '%s': (%d) %s", file, ret, | 260 | return apr_psprintf(parms->pool, |
243 | gnutls_strerror(ret)); | 261 | "GnuTLS: Failed to Import " |
244 | } | 262 | "PGP Certificate '%s': (%d) %s", file, |
245 | 263 | ret, gnutls_strerror(ret)); | |
246 | apr_pool_destroy(spool); | 264 | } |
247 | return NULL; | 265 | |
266 | apr_pool_destroy(spool); | ||
267 | return NULL; | ||
248 | } | 268 | } |
249 | 269 | ||
250 | const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy, | 270 | const char *mgs_set_pgpkey_file(cmd_parms * parms, void *dummy, |
251 | const char *arg) | 271 | const char *arg) |
252 | { | 272 | { |
253 | int ret; | 273 | int ret; |
254 | gnutls_datum_t data; | 274 | gnutls_datum_t data; |
255 | const char *file; | 275 | const char *file; |
256 | apr_pool_t *spool; | 276 | apr_pool_t *spool; |
257 | mgs_srvconf_rec *sc = | 277 | mgs_srvconf_rec *sc = |
258 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 278 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
259 | module_config, | 279 | module_config, |
260 | &gnutls_module); | 280 | &gnutls_module); |
261 | apr_pool_create(&spool, parms->pool); | 281 | apr_pool_create(&spool, parms->pool); |
262 | 282 | ||
263 | file = ap_server_root_relative(spool, arg); | 283 | file = ap_server_root_relative(spool, arg); |
264 | 284 | ||
265 | if (load_datum_from_file(spool, file, &data) != 0) { | 285 | if (load_datum_from_file(spool, file, &data) != 0) { |
266 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " | 286 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " |
267 | "Private Key '%s'", file); | 287 | "Private Key '%s'", file); |
268 | } | 288 | } |
269 | 289 | ||
270 | ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp); | 290 | ret = gnutls_openpgp_privkey_init(&sc->privkey_pgp); |
271 | if (ret < 0) { | 291 | if (ret < 0) { |
272 | return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" | 292 | return apr_psprintf(parms->pool, |
273 | ": (%d) %s", ret, gnutls_strerror(ret)); | 293 | "GnuTLS: Failed to initialize" |
274 | } | 294 | ": (%d) %s", ret, |
275 | 295 | gnutls_strerror(ret)); | |
276 | ret = | 296 | } |
277 | gnutls_openpgp_privkey_import(sc->privkey_pgp, &data, | 297 | |
278 | GNUTLS_OPENPGP_FMT_BASE64, NULL, 0); | 298 | ret = |
279 | if (ret != 0) { | 299 | gnutls_openpgp_privkey_import(sc->privkey_pgp, &data, |
280 | return apr_psprintf(parms->pool, "GnuTLS: Failed to Import " | 300 | GNUTLS_OPENPGP_FMT_BASE64, NULL, |
281 | "PGP Private Key '%s': (%d) %s", file, ret, | 301 | 0); |
282 | gnutls_strerror(ret)); | 302 | if (ret != 0) { |
283 | } | 303 | return apr_psprintf(parms->pool, |
284 | apr_pool_destroy(spool); | 304 | "GnuTLS: Failed to Import " |
285 | return NULL; | 305 | "PGP Private Key '%s': (%d) %s", file, |
306 | ret, gnutls_strerror(ret)); | ||
307 | } | ||
308 | apr_pool_destroy(spool); | ||
309 | return NULL; | ||
286 | } | 310 | } |
287 | 311 | ||
288 | const char *mgs_set_tickets(cmd_parms * parms, void *dummy, | 312 | const char *mgs_set_tickets(cmd_parms * parms, void *dummy, |
289 | const char *arg) | 313 | const char *arg) |
290 | { | 314 | { |
291 | mgs_srvconf_rec *sc = | 315 | mgs_srvconf_rec *sc = |
292 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 316 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
293 | module_config, | 317 | module_config, |
294 | &gnutls_module); | 318 | &gnutls_module); |
295 | 319 | ||
296 | sc->tickets = 0; | 320 | sc->tickets = 0; |
297 | if (strcasecmp("on", arg) == 0) { | 321 | if (strcasecmp("on", arg) == 0) { |
298 | sc->tickets = 1; | 322 | sc->tickets = 1; |
299 | } | 323 | } |
300 | 324 | ||
301 | return NULL; | 325 | return NULL; |
302 | } | 326 | } |
303 | 327 | ||
304 | 328 | ||
@@ -307,27 +331,28 @@ const char *mgs_set_tickets(cmd_parms * parms, void *dummy, | |||
307 | const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy, | 331 | const char *mgs_set_srp_tpasswd_file(cmd_parms * parms, void *dummy, |
308 | const char *arg) | 332 | const char *arg) |
309 | { | 333 | { |
310 | mgs_srvconf_rec *sc = | 334 | mgs_srvconf_rec *sc = |
311 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 335 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
312 | module_config, | 336 | module_config, |
313 | &gnutls_module); | 337 | &gnutls_module); |
314 | 338 | ||
315 | sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg); | 339 | sc->srp_tpasswd_file = ap_server_root_relative(parms->pool, arg); |
316 | 340 | ||
317 | return NULL; | 341 | return NULL; |
318 | } | 342 | } |
319 | 343 | ||
320 | const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy, | 344 | const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy, |
321 | const char *arg) | 345 | const char *arg) |
322 | { | 346 | { |
323 | mgs_srvconf_rec *sc = | 347 | mgs_srvconf_rec *sc = |
324 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 348 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
325 | module_config, | 349 | module_config, |
326 | &gnutls_module); | 350 | &gnutls_module); |
327 | 351 | ||
328 | sc->srp_tpasswd_conf_file = ap_server_root_relative(parms->pool, arg); | 352 | sc->srp_tpasswd_conf_file = |
353 | ap_server_root_relative(parms->pool, arg); | ||
329 | 354 | ||
330 | return NULL; | 355 | return NULL; |
331 | } | 356 | } |
332 | 357 | ||
333 | #endif | 358 | #endif |
@@ -335,308 +360,326 @@ const char *mgs_set_srp_tpasswd_conf_file(cmd_parms * parms, void *dummy, | |||
335 | const char *mgs_set_cache(cmd_parms * parms, void *dummy, | 360 | const char *mgs_set_cache(cmd_parms * parms, void *dummy, |
336 | const char *type, const char *arg) | 361 | const char *type, const char *arg) |
337 | { | 362 | { |
338 | const char *err; | 363 | const char *err; |
339 | mgs_srvconf_rec *sc = ap_get_module_config(parms->server-> | 364 | mgs_srvconf_rec *sc = |
340 | module_config, | 365 | ap_get_module_config(parms->server->module_config, |
341 | &gnutls_module); | 366 | &gnutls_module); |
342 | if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) { | 367 | if ((err = ap_check_cmd_context(parms, GLOBAL_ONLY))) { |
343 | return err; | 368 | return err; |
344 | } | 369 | } |
345 | 370 | ||
346 | if (strcasecmp("none", type) == 0) { | 371 | if (strcasecmp("none", type) == 0) { |
347 | sc->cache_type = mgs_cache_none; | 372 | sc->cache_type = mgs_cache_none; |
348 | } else if (strcasecmp("dbm", type) == 0) { | 373 | } else if (strcasecmp("dbm", type) == 0) { |
349 | sc->cache_type = mgs_cache_dbm; | 374 | sc->cache_type = mgs_cache_dbm; |
350 | } | 375 | } else if (strcasecmp("gdbm", type) == 0) { |
351 | else if (strcasecmp("gdbm", type) == 0) { | 376 | sc->cache_type = mgs_cache_gdbm; |
352 | sc->cache_type = mgs_cache_gdbm; | 377 | } |
353 | } | ||
354 | #if HAVE_APR_MEMCACHE | 378 | #if HAVE_APR_MEMCACHE |
355 | else if (strcasecmp("memcache", type) == 0) { | 379 | else if (strcasecmp("memcache", type) == 0) { |
356 | sc->cache_type = mgs_cache_memcache; | 380 | sc->cache_type = mgs_cache_memcache; |
357 | } | 381 | } |
358 | #endif | 382 | #endif |
359 | else { | 383 | else { |
360 | return "Invalid Type for GnuTLSCache!"; | 384 | return "Invalid Type for GnuTLSCache!"; |
361 | } | 385 | } |
362 | 386 | ||
363 | if (sc->cache_type == mgs_cache_dbm || sc->cache_type == mgs_cache_gdbm) { | 387 | if (sc->cache_type == mgs_cache_dbm |
364 | sc->cache_config = ap_server_root_relative(parms->pool, arg); | 388 | || sc->cache_type == mgs_cache_gdbm) { |
365 | } else { | 389 | sc->cache_config = |
366 | sc->cache_config = apr_pstrdup(parms->pool, arg); | 390 | ap_server_root_relative(parms->pool, arg); |
367 | } | 391 | } else { |
368 | 392 | sc->cache_config = apr_pstrdup(parms->pool, arg); | |
369 | return NULL; | 393 | } |
394 | |||
395 | return NULL; | ||
370 | } | 396 | } |
371 | 397 | ||
372 | const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy, | 398 | const char *mgs_set_cache_timeout(cmd_parms * parms, void *dummy, |
373 | const char *arg) | 399 | const char *arg) |
374 | { | 400 | { |
375 | int argint; | 401 | int argint; |
376 | mgs_srvconf_rec *sc = | ||
377 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | ||
378 | module_config, | ||
379 | &gnutls_module); | ||
380 | |||
381 | argint = atoi(arg); | ||
382 | |||
383 | if (argint < 0) { | ||
384 | return "GnuTLSCacheTimeout: Invalid argument"; | ||
385 | } else if (argint == 0) { | ||
386 | sc->cache_timeout = 0; | ||
387 | } else { | ||
388 | sc->cache_timeout = apr_time_from_sec(argint); | ||
389 | } | ||
390 | |||
391 | return NULL; | ||
392 | } | ||
393 | |||
394 | const char *mgs_set_client_verify(cmd_parms * parms, void *dummy, | ||
395 | const char *arg) | ||
396 | { | ||
397 | int mode; | ||
398 | |||
399 | if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) { | ||
400 | mode = GNUTLS_CERT_IGNORE; | ||
401 | } else if (strcasecmp("optional", arg) == 0 | ||
402 | || strcasecmp("request", arg) == 0) { | ||
403 | mode = GNUTLS_CERT_REQUEST; | ||
404 | } else if (strcasecmp("require", arg) == 0) { | ||
405 | mode = GNUTLS_CERT_REQUIRE; | ||
406 | } else { | ||
407 | return "GnuTLSClientVerify: Invalid argument"; | ||
408 | } | ||
409 | |||
410 | /* This was set from a directory context */ | ||
411 | if (parms->path) { | ||
412 | mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy; | ||
413 | dc->client_verify_mode = mode; | ||
414 | } else { | ||
415 | mgs_srvconf_rec *sc = | 402 | mgs_srvconf_rec *sc = |
416 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 403 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
417 | module_config, | 404 | module_config, |
418 | &gnutls_module); | 405 | &gnutls_module); |
419 | sc->client_verify_mode = mode; | ||
420 | } | ||
421 | 406 | ||
422 | return NULL; | 407 | argint = atoi(arg); |
408 | |||
409 | if (argint < 0) { | ||
410 | return "GnuTLSCacheTimeout: Invalid argument"; | ||
411 | } else if (argint == 0) { | ||
412 | sc->cache_timeout = 0; | ||
413 | } else { | ||
414 | sc->cache_timeout = apr_time_from_sec(argint); | ||
415 | } | ||
416 | |||
417 | return NULL; | ||
418 | } | ||
419 | |||
420 | const char *mgs_set_client_verify(cmd_parms * parms, void *dummy, | ||
421 | const char *arg) | ||
422 | { | ||
423 | int mode; | ||
424 | |||
425 | if (strcasecmp("none", arg) == 0 || strcasecmp("ignore", arg) == 0) { | ||
426 | mode = GNUTLS_CERT_IGNORE; | ||
427 | } else if (strcasecmp("optional", arg) == 0 | ||
428 | || strcasecmp("request", arg) == 0) { | ||
429 | mode = GNUTLS_CERT_REQUEST; | ||
430 | } else if (strcasecmp("require", arg) == 0) { | ||
431 | mode = GNUTLS_CERT_REQUIRE; | ||
432 | } else { | ||
433 | return "GnuTLSClientVerify: Invalid argument"; | ||
434 | } | ||
435 | |||
436 | /* This was set from a directory context */ | ||
437 | if (parms->path) { | ||
438 | mgs_dirconf_rec *dc = (mgs_dirconf_rec *) dummy; | ||
439 | dc->client_verify_mode = mode; | ||
440 | } else { | ||
441 | mgs_srvconf_rec *sc = | ||
442 | (mgs_srvconf_rec *) | ||
443 | ap_get_module_config(parms->server->module_config, | ||
444 | &gnutls_module); | ||
445 | sc->client_verify_mode = mode; | ||
446 | } | ||
447 | |||
448 | return NULL; | ||
423 | } | 449 | } |
424 | 450 | ||
425 | #define INIT_CA_SIZE 128 | 451 | #define INIT_CA_SIZE 128 |
426 | const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy, | 452 | const char *mgs_set_client_ca_file(cmd_parms * parms, void *dummy, |
427 | const char *arg) | 453 | const char *arg) |
428 | { | 454 | { |
429 | int rv; | 455 | int rv; |
430 | const char *file; | 456 | const char *file; |
431 | apr_pool_t *spool; | 457 | apr_pool_t *spool; |
432 | gnutls_datum_t data; | 458 | gnutls_datum_t data; |
433 | 459 | ||
434 | mgs_srvconf_rec *sc = | 460 | mgs_srvconf_rec *sc = |
435 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 461 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
436 | module_config, | 462 | module_config, |
437 | &gnutls_module); | 463 | &gnutls_module); |
438 | apr_pool_create(&spool, parms->pool); | 464 | apr_pool_create(&spool, parms->pool); |
439 | 465 | ||
440 | file = ap_server_root_relative(spool, arg); | 466 | file = ap_server_root_relative(spool, arg); |
441 | 467 | ||
442 | if (load_datum_from_file(spool, file, &data) != 0) { | 468 | if (load_datum_from_file(spool, file, &data) != 0) { |
443 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " | 469 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " |
444 | "Client CA File '%s'", file); | 470 | "Client CA File '%s'", file); |
445 | } | 471 | } |
446 | 472 | ||
447 | sc->ca_list_size = INIT_CA_SIZE; | 473 | sc->ca_list_size = INIT_CA_SIZE; |
448 | sc->ca_list = malloc(sc->ca_list_size * sizeof(*sc->ca_list)); | 474 | sc->ca_list = malloc(sc->ca_list_size * sizeof(*sc->ca_list)); |
449 | if (sc->ca_list == NULL) { | 475 | if (sc->ca_list == NULL) { |
450 | return apr_psprintf(parms->pool, "mod_gnutls: Memory allocation error"); | 476 | return apr_psprintf(parms->pool, |
451 | } | 477 | "mod_gnutls: Memory allocation error"); |
452 | 478 | } | |
453 | rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size, | 479 | |
454 | &data, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); | 480 | rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size, |
455 | if (rv < 0 && rv != GNUTLS_E_SHORT_MEMORY_BUFFER) { | 481 | &data, GNUTLS_X509_FMT_PEM, |
456 | return apr_psprintf(parms->pool, "GnuTLS: Failed to load " | 482 | GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED); |
457 | "Client CA File '%s': (%d) %s", file, rv, | 483 | if (rv < 0 && rv != GNUTLS_E_SHORT_MEMORY_BUFFER) { |
458 | gnutls_strerror(rv)); | 484 | return apr_psprintf(parms->pool, "GnuTLS: Failed to load " |
459 | } | 485 | "Client CA File '%s': (%d) %s", file, |
460 | 486 | rv, gnutls_strerror(rv)); | |
461 | if (INIT_CA_SIZE < sc->ca_list_size) { | 487 | } |
462 | sc->ca_list = realloc(sc->ca_list, sc->ca_list_size*sizeof(*sc->ca_list)); | 488 | |
463 | if (sc->ca_list == NULL) { | 489 | if (INIT_CA_SIZE < sc->ca_list_size) { |
464 | return apr_psprintf(parms->pool, "mod_gnutls: Memory allocation error"); | 490 | sc->ca_list = |
465 | } | 491 | realloc(sc->ca_list, |
466 | 492 | sc->ca_list_size * sizeof(*sc->ca_list)); | |
467 | /* re-read */ | 493 | if (sc->ca_list == NULL) { |
468 | rv = gnutls_x509_crt_list_import(sc->ca_list, &sc->ca_list_size, | 494 | return apr_psprintf(parms->pool, |
469 | &data, GNUTLS_X509_FMT_PEM, 0); | 495 | "mod_gnutls: Memory allocation error"); |
470 | 496 | } | |
471 | if (rv < 0) { | 497 | |
472 | return apr_psprintf(parms->pool, "GnuTLS: Failed to load " | 498 | /* re-read */ |
473 | "Client CA File '%s': (%d) %s", file, rv, | 499 | rv = gnutls_x509_crt_list_import(sc->ca_list, |
474 | gnutls_strerror(rv)); | 500 | &sc->ca_list_size, &data, |
475 | } | 501 | GNUTLS_X509_FMT_PEM, 0); |
476 | } | 502 | |
477 | 503 | if (rv < 0) { | |
478 | apr_pool_destroy(spool); | 504 | return apr_psprintf(parms->pool, |
479 | return NULL; | 505 | "GnuTLS: Failed to load " |
506 | "Client CA File '%s': (%d) %s", | ||
507 | file, rv, gnutls_strerror(rv)); | ||
508 | } | ||
509 | } | ||
510 | |||
511 | apr_pool_destroy(spool); | ||
512 | return NULL; | ||
480 | } | 513 | } |
481 | 514 | ||
482 | const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy, | 515 | const char *mgs_set_keyring_file(cmd_parms * parms, void *dummy, |
483 | const char *arg) | 516 | const char *arg) |
484 | { | 517 | { |
485 | int rv; | 518 | int rv; |
486 | const char *file; | 519 | const char *file; |
487 | apr_pool_t *spool; | 520 | apr_pool_t *spool; |
488 | gnutls_datum_t data; | 521 | gnutls_datum_t data; |
489 | 522 | ||
490 | mgs_srvconf_rec *sc = | 523 | mgs_srvconf_rec *sc = |
491 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 524 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
492 | module_config, | 525 | module_config, |
493 | &gnutls_module); | 526 | &gnutls_module); |
494 | apr_pool_create(&spool, parms->pool); | 527 | apr_pool_create(&spool, parms->pool); |
495 | 528 | ||
496 | file = ap_server_root_relative(spool, arg); | 529 | file = ap_server_root_relative(spool, arg); |
497 | 530 | ||
498 | if (load_datum_from_file(spool, file, &data) != 0) { | 531 | if (load_datum_from_file(spool, file, &data) != 0) { |
499 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " | 532 | return apr_psprintf(parms->pool, "GnuTLS: Error Reading " |
500 | "Keyring File '%s'", file); | 533 | "Keyring File '%s'", file); |
501 | } | 534 | } |
502 | 535 | ||
503 | rv = gnutls_openpgp_keyring_init(&sc->pgp_list); | 536 | rv = gnutls_openpgp_keyring_init(&sc->pgp_list); |
504 | if (rv < 0) { | 537 | if (rv < 0) { |
505 | return apr_psprintf(parms->pool, "GnuTLS: Failed to initialize" | 538 | return apr_psprintf(parms->pool, |
506 | "keyring: (%d) %s", rv, gnutls_strerror(rv)); | 539 | "GnuTLS: Failed to initialize" |
507 | } | 540 | "keyring: (%d) %s", rv, |
508 | 541 | gnutls_strerror(rv)); | |
509 | rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, GNUTLS_OPENPGP_FMT_BASE64); | 542 | } |
510 | if (rv < 0) { | 543 | |
511 | return apr_psprintf(parms->pool, "GnuTLS: Failed to load " | 544 | rv = gnutls_openpgp_keyring_import(sc->pgp_list, &data, |
512 | "Keyring File '%s': (%d) %s", file, rv, | 545 | GNUTLS_OPENPGP_FMT_BASE64); |
513 | gnutls_strerror(rv)); | 546 | if (rv < 0) { |
514 | } | 547 | return apr_psprintf(parms->pool, "GnuTLS: Failed to load " |
515 | 548 | "Keyring File '%s': (%d) %s", file, rv, | |
516 | apr_pool_destroy(spool); | 549 | gnutls_strerror(rv)); |
517 | return NULL; | 550 | } |
551 | |||
552 | apr_pool_destroy(spool); | ||
553 | return NULL; | ||
518 | } | 554 | } |
519 | 555 | ||
520 | const char *mgs_set_enabled(cmd_parms * parms, void *dummy, | 556 | const char *mgs_set_enabled(cmd_parms * parms, void *dummy, |
521 | const char *arg) | 557 | const char *arg) |
522 | { | 558 | { |
523 | mgs_srvconf_rec *sc = | 559 | mgs_srvconf_rec *sc = |
524 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 560 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
525 | module_config, | 561 | module_config, |
526 | &gnutls_module); | 562 | &gnutls_module); |
527 | if (!strcasecmp(arg, "On")) { | 563 | if (!strcasecmp(arg, "On")) { |
528 | sc->enabled = GNUTLS_ENABLED_TRUE; | 564 | sc->enabled = GNUTLS_ENABLED_TRUE; |
529 | } else if (!strcasecmp(arg, "Off")) { | 565 | } else if (!strcasecmp(arg, "Off")) { |
530 | sc->enabled = GNUTLS_ENABLED_FALSE; | 566 | sc->enabled = GNUTLS_ENABLED_FALSE; |
531 | } else { | 567 | } else { |
532 | return "GnuTLSEnable must be set to 'On' or 'Off'"; | 568 | return "GnuTLSEnable must be set to 'On' or 'Off'"; |
533 | } | 569 | } |
534 | 570 | ||
535 | return NULL; | 571 | return NULL; |
536 | } | 572 | } |
537 | 573 | ||
538 | const char *mgs_set_export_certificates_enabled(cmd_parms * parms, void *dummy, | 574 | const char *mgs_set_export_certificates_enabled(cmd_parms * parms, |
539 | const char *arg) | 575 | void *dummy, |
576 | const char *arg) | ||
540 | { | 577 | { |
541 | mgs_srvconf_rec *sc = | 578 | mgs_srvconf_rec *sc = |
542 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 579 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
543 | module_config, | 580 | module_config, |
544 | &gnutls_module); | 581 | &gnutls_module); |
545 | if (!strcasecmp(arg, "On")) { | 582 | if (!strcasecmp(arg, "On")) { |
546 | sc->export_certificates_enabled = GNUTLS_ENABLED_TRUE; | 583 | sc->export_certificates_enabled = GNUTLS_ENABLED_TRUE; |
547 | } else if (!strcasecmp(arg, "Off")) { | 584 | } else if (!strcasecmp(arg, "Off")) { |
548 | sc->export_certificates_enabled = GNUTLS_ENABLED_FALSE; | 585 | sc->export_certificates_enabled = GNUTLS_ENABLED_FALSE; |
549 | } else { | 586 | } else { |
550 | return "GnuTLSExportCertificates must be set to 'On' or 'Off'"; | 587 | return |
551 | } | 588 | "GnuTLSExportCertificates must be set to 'On' or 'Off'"; |
552 | 589 | } | |
553 | return NULL; | 590 | |
591 | return NULL; | ||
554 | } | 592 | } |
555 | 593 | ||
556 | 594 | ||
557 | const char *mgs_set_priorities(cmd_parms * parms, void *dummy, const char *arg) | 595 | const char *mgs_set_priorities(cmd_parms * parms, void *dummy, |
596 | const char *arg) | ||
558 | { | 597 | { |
559 | int ret; | 598 | int ret; |
560 | const char *err; | 599 | const char *err; |
561 | mgs_srvconf_rec *sc = | 600 | mgs_srvconf_rec *sc = |
562 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> | 601 | (mgs_srvconf_rec *) ap_get_module_config(parms->server-> |
563 | module_config, | 602 | module_config, |
564 | &gnutls_module); | 603 | &gnutls_module); |
565 | 604 | ||
566 | 605 | ||
567 | ret = gnutls_priority_init( &sc->priorities, arg, &err); | 606 | ret = gnutls_priority_init(&sc->priorities, arg, &err); |
568 | if (ret < 0) { | 607 | if (ret < 0) { |
569 | if (ret == GNUTLS_E_INVALID_REQUEST) | 608 | if (ret == GNUTLS_E_INVALID_REQUEST) |
570 | return apr_psprintf(parms->pool, "GnuTLS: Syntax error parsing priorities string at: %s", err); | 609 | return apr_psprintf(parms->pool, |
571 | return "Error setting priorities"; | 610 | "GnuTLS: Syntax error parsing priorities string at: %s", |
572 | } | 611 | err); |
573 | 612 | return "Error setting priorities"; | |
574 | return NULL; | 613 | } |
614 | |||
615 | return NULL; | ||
575 | } | 616 | } |
576 | 617 | ||
577 | void *mgs_config_server_create(apr_pool_t * p, server_rec * s) | 618 | void *mgs_config_server_create(apr_pool_t * p, server_rec * s) |
578 | { | 619 | { |
579 | mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc)); | 620 | mgs_srvconf_rec *sc = apr_pcalloc(p, sizeof(*sc)); |
580 | int ret; | 621 | int ret; |
581 | |||
582 | sc->enabled = GNUTLS_ENABLED_FALSE; | ||
583 | |||
584 | ret = gnutls_certificate_allocate_credentials(&sc->certs); | ||
585 | if (ret < 0) { | ||
586 | return apr_psprintf(p, "GnuTLS: Failed to initialize" | ||
587 | ": (%d) %s", ret, gnutls_strerror(ret)); | ||
588 | } | ||
589 | |||
590 | ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds); | ||
591 | if (ret < 0) { | ||
592 | return apr_psprintf(p, "GnuTLS: Failed to initialize" | ||
593 | ": (%d) %s", ret, gnutls_strerror(ret)); | ||
594 | } | ||
595 | 622 | ||
623 | sc->enabled = GNUTLS_ENABLED_FALSE; | ||
624 | |||
625 | ret = gnutls_certificate_allocate_credentials(&sc->certs); | ||
626 | if (ret < 0) { | ||
627 | return apr_psprintf(p, "GnuTLS: Failed to initialize" | ||
628 | ": (%d) %s", ret, | ||
629 | gnutls_strerror(ret)); | ||
630 | } | ||
631 | |||
632 | ret = gnutls_anon_allocate_server_credentials(&sc->anon_creds); | ||
633 | if (ret < 0) { | ||
634 | return apr_psprintf(p, "GnuTLS: Failed to initialize" | ||
635 | ": (%d) %s", ret, | ||
636 | gnutls_strerror(ret)); | ||
637 | } | ||
596 | #ifdef ENABLE_SRP | 638 | #ifdef ENABLE_SRP |
597 | ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds); | 639 | ret = gnutls_srp_allocate_server_credentials(&sc->srp_creds); |
598 | if (ret < 0) { | 640 | if (ret < 0) { |
599 | return apr_psprintf(p, "GnuTLS: Failed to initialize" | 641 | return apr_psprintf(p, "GnuTLS: Failed to initialize" |
600 | ": (%d) %s", ret, gnutls_strerror(ret)); | 642 | ": (%d) %s", ret, |
601 | } | 643 | gnutls_strerror(ret)); |
602 | 644 | } | |
603 | sc->srp_tpasswd_conf_file = NULL; | 645 | |
604 | sc->srp_tpasswd_file = NULL; | 646 | sc->srp_tpasswd_conf_file = NULL; |
647 | sc->srp_tpasswd_file = NULL; | ||
605 | #endif | 648 | #endif |
606 | 649 | ||
607 | sc->privkey_x509 = NULL; | 650 | sc->privkey_x509 = NULL; |
608 | memset( sc->certs_x509, 0, sizeof(sc->certs_x509)); | 651 | memset(sc->certs_x509, 0, sizeof(sc->certs_x509)); |
609 | sc->certs_x509_num = 0; | 652 | sc->certs_x509_num = 0; |
610 | sc->cache_timeout = apr_time_from_sec(300); | 653 | sc->cache_timeout = apr_time_from_sec(300); |
611 | sc->cache_type = mgs_cache_none; | 654 | sc->cache_type = mgs_cache_none; |
612 | sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache"); | 655 | sc->cache_config = ap_server_root_relative(p, "conf/gnutls_cache"); |
613 | sc->tickets = 1; /* by default enable session tickets */ | 656 | sc->tickets = 1; /* by default enable session tickets */ |
614 | 657 | ||
615 | sc->client_verify_mode = GNUTLS_CERT_IGNORE; | 658 | sc->client_verify_mode = GNUTLS_CERT_IGNORE; |
616 | 659 | ||
617 | return sc; | 660 | return sc; |
618 | } | 661 | } |
619 | 662 | ||
620 | void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv) | 663 | void *mgs_config_dir_merge(apr_pool_t * p, void *basev, void *addv) |
621 | { | 664 | { |
622 | mgs_dirconf_rec *new; | 665 | mgs_dirconf_rec *new; |
623 | /* mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */ | 666 | /* mgs_dirconf_rec *base = (mgs_dirconf_rec *) basev; */ |
624 | mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv; | 667 | mgs_dirconf_rec *add = (mgs_dirconf_rec *) addv; |
625 | 668 | ||
626 | new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec)); | 669 | new = (mgs_dirconf_rec *) apr_pcalloc(p, sizeof(mgs_dirconf_rec)); |
627 | new->lua_bytecode = apr_pstrmemdup(p, add->lua_bytecode, | 670 | new->lua_bytecode = apr_pstrmemdup(p, add->lua_bytecode, |
628 | add->lua_bytecode_len); | 671 | add->lua_bytecode_len); |
629 | new->lua_bytecode_len = add->lua_bytecode_len; | 672 | new->lua_bytecode_len = add->lua_bytecode_len; |
630 | new->client_verify_mode = add->client_verify_mode; | 673 | new->client_verify_mode = add->client_verify_mode; |
631 | return new; | 674 | return new; |
632 | } | 675 | } |
633 | 676 | ||
634 | void *mgs_config_dir_create(apr_pool_t * p, char *dir) | 677 | void *mgs_config_dir_create(apr_pool_t * p, char *dir) |
635 | { | 678 | { |
636 | mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc)); | 679 | mgs_dirconf_rec *dc = apr_palloc(p, sizeof(*dc)); |
637 | 680 | ||
638 | dc->client_verify_mode = -1; | 681 | dc->client_verify_mode = -1; |
639 | dc->lua_bytecode = NULL; | 682 | dc->lua_bytecode = NULL; |
640 | dc->lua_bytecode_len = 0; | 683 | dc->lua_bytecode_len = 0; |
641 | return dc; | 684 | return dc; |
642 | } | 685 | } |
diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c index 7c638fb..34c3585 100644 --- a/src/gnutls_hooks.c +++ b/src/gnutls_hooks.c | |||
@@ -40,179 +40,191 @@ static gnutls_datum session_ticket_key = { NULL, 0 }; | |||
40 | 40 | ||
41 | static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt); | 41 | static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt); |
42 | /* use side==0 for server and side==1 for client */ | 42 | /* use side==0 for server and side==1 for client */ |
43 | static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, | 43 | static void mgs_add_common_cert_vars(request_rec * r, |
44 | int side, | 44 | gnutls_x509_crt_t cert, int side, |
45 | int export_certificates_enabled); | ||
46 | static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, | ||
47 | int side, | ||
48 | int export_certificates_enabled); | 45 | int export_certificates_enabled); |
46 | static void mgs_add_common_pgpcert_vars(request_rec * r, | ||
47 | gnutls_openpgp_crt_t cert, | ||
48 | int side, | ||
49 | int export_certificates_enabled); | ||
49 | 50 | ||
50 | static apr_status_t mgs_cleanup_pre_config(void *data) | 51 | static apr_status_t mgs_cleanup_pre_config(void *data) |
51 | { | 52 | { |
52 | gnutls_free(session_ticket_key.data); | 53 | gnutls_free(session_ticket_key.data); |
53 | session_ticket_key.data = NULL; | 54 | session_ticket_key.data = NULL; |
54 | session_ticket_key.size = 0; | 55 | session_ticket_key.size = 0; |
55 | gnutls_global_deinit(); | 56 | gnutls_global_deinit(); |
56 | return APR_SUCCESS; | 57 | return APR_SUCCESS; |
57 | } | 58 | } |
58 | 59 | ||
59 | #if MOD_GNUTLS_DEBUG | 60 | #if MOD_GNUTLS_DEBUG |
60 | static void gnutls_debug_log_all(int level, const char *str) | 61 | static void gnutls_debug_log_all(int level, const char *str) |
61 | { | 62 | { |
62 | apr_file_printf(debug_log_fp, "<%d> %s\n", level, str); | 63 | apr_file_printf(debug_log_fp, "<%d> %s\n", level, str); |
63 | } | 64 | } |
65 | |||
64 | #define _gnutls_log apr_file_printf | 66 | #define _gnutls_log apr_file_printf |
65 | #else | 67 | #else |
66 | # define _gnutls_log(...) | 68 | # define _gnutls_log(...) |
67 | #endif | 69 | #endif |
68 | 70 | ||
69 | int | 71 | int |
70 | mgs_hook_pre_config(apr_pool_t * pconf, | 72 | mgs_hook_pre_config(apr_pool_t * pconf, |
71 | apr_pool_t * plog, apr_pool_t * ptemp) | 73 | apr_pool_t * plog, apr_pool_t * ptemp) |
72 | { | 74 | { |
73 | int ret; | 75 | int ret; |
74 | 76 | ||
75 | #if MOD_GNUTLS_DEBUG | 77 | #if MOD_GNUTLS_DEBUG |
76 | apr_file_open(&debug_log_fp, "/tmp/gnutls_debug", | 78 | apr_file_open(&debug_log_fp, "/tmp/gnutls_debug", |
77 | APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT, | 79 | APR_APPEND | APR_WRITE | APR_CREATE, APR_OS_DEFAULT, |
78 | pconf); | 80 | pconf); |
79 | 81 | ||
80 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 82 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
81 | 83 | ||
82 | gnutls_global_set_log_level(9); | 84 | gnutls_global_set_log_level(9); |
83 | gnutls_global_set_log_function(gnutls_debug_log_all); | 85 | gnutls_global_set_log_function(gnutls_debug_log_all); |
84 | _gnutls_log(debug_log_fp, "gnutls: %s\n", gnutls_check_version(NULL)); | 86 | _gnutls_log(debug_log_fp, "gnutls: %s\n", |
87 | gnutls_check_version(NULL)); | ||
85 | #endif | 88 | #endif |
86 | 89 | ||
87 | #if APR_HAS_THREADS | 90 | #if APR_HAS_THREADS |
88 | ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_is_threaded); | 91 | ap_mpm_query(AP_MPMQ_IS_THREADED, &mpm_is_threaded); |
89 | #if (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR < 11) || GNUTLS_VERSION_MAJOR < 2 | 92 | #if (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR < 11) || GNUTLS_VERSION_MAJOR < 2 |
90 | if (mpm_is_threaded) { | 93 | if (mpm_is_threaded) { |
91 | gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); | 94 | gcry_control(GCRYCTL_SET_THREAD_CBS, |
92 | } | 95 | &gcry_threads_pthread); |
96 | } | ||
93 | #endif | 97 | #endif |
94 | #else | 98 | #else |
95 | mpm_is_threaded = 0; | 99 | mpm_is_threaded = 0; |
96 | #endif | 100 | #endif |
97 | 101 | ||
98 | 102 | ||
99 | if (gnutls_check_version(LIBGNUTLS_VERSION)==NULL) { | 103 | if (gnutls_check_version(LIBGNUTLS_VERSION) == NULL) { |
100 | _gnutls_log(debug_log_fp, "gnutls_check_version() failed. Required: gnutls-%s Found: gnutls-%s\n", | 104 | _gnutls_log(debug_log_fp, |
101 | LIBGNUTLS_VERSION, gnutls_check_version(NULL)); | 105 | "gnutls_check_version() failed. Required: gnutls-%s Found: gnutls-%s\n", |
102 | return -3; | 106 | LIBGNUTLS_VERSION, gnutls_check_version(NULL)); |
103 | } | 107 | return -3; |
108 | } | ||
109 | |||
110 | ret = gnutls_global_init(); | ||
111 | if (ret < 0) { | ||
112 | _gnutls_log(debug_log_fp, "gnutls_global_init: %s\n", | ||
113 | gnutls_strerror(ret)); | ||
114 | return -3; | ||
115 | } | ||
104 | 116 | ||
105 | ret = gnutls_global_init(); | 117 | ret = gnutls_session_ticket_key_generate(&session_ticket_key); |
106 | if (ret < 0) { | 118 | if (ret < 0) { |
107 | _gnutls_log(debug_log_fp, "gnutls_global_init: %s\n", gnutls_strerror(ret)); | 119 | _gnutls_log(debug_log_fp, |
108 | return -3; | 120 | "gnutls_session_ticket_key_generate: %s\n", |
109 | } | 121 | gnutls_strerror(ret)); |
110 | 122 | } | |
111 | ret = gnutls_session_ticket_key_generate( &session_ticket_key); | ||
112 | if (ret < 0) { | ||
113 | _gnutls_log(debug_log_fp, "gnutls_session_ticket_key_generate: %s\n", gnutls_strerror(ret)); | ||
114 | } | ||
115 | 123 | ||
116 | apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config, | 124 | apr_pool_cleanup_register(pconf, NULL, mgs_cleanup_pre_config, |
117 | apr_pool_cleanup_null); | 125 | apr_pool_cleanup_null); |
118 | 126 | ||
119 | 127 | ||
120 | return OK; | 128 | return OK; |
121 | } | 129 | } |
122 | 130 | ||
123 | static int mgs_select_virtual_server_cb(gnutls_session_t session) | 131 | static int mgs_select_virtual_server_cb(gnutls_session_t session) |
124 | { | 132 | { |
125 | mgs_handle_t *ctxt; | 133 | mgs_handle_t *ctxt; |
126 | mgs_srvconf_rec *tsc; | 134 | mgs_srvconf_rec *tsc; |
127 | int ret; | 135 | int ret; |
128 | int cprio[2]; | 136 | int cprio[2]; |
129 | 137 | ||
130 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 138 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
131 | 139 | ||
132 | ctxt = gnutls_transport_get_ptr(session); | 140 | ctxt = gnutls_transport_get_ptr(session); |
133 | 141 | ||
134 | /* find the virtual server */ | 142 | /* find the virtual server */ |
135 | tsc = mgs_find_sni_server(session); | 143 | tsc = mgs_find_sni_server(session); |
136 | 144 | ||
137 | if (tsc != NULL) | 145 | if (tsc != NULL) |
138 | ctxt->sc = tsc; | 146 | ctxt->sc = tsc; |
139 | 147 | ||
140 | gnutls_certificate_server_set_request(session, | 148 | gnutls_certificate_server_set_request(session, |
141 | ctxt->sc->client_verify_mode); | 149 | ctxt-> |
150 | sc->client_verify_mode); | ||
142 | 151 | ||
143 | /* set the new server credentials | 152 | /* set the new server credentials |
144 | */ | 153 | */ |
145 | 154 | ||
146 | gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, | 155 | gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, |
147 | ctxt->sc->certs); | 156 | ctxt->sc->certs); |
148 | 157 | ||
149 | gnutls_credentials_set(session, GNUTLS_CRD_ANON, ctxt->sc->anon_creds); | 158 | gnutls_credentials_set(session, GNUTLS_CRD_ANON, |
159 | ctxt->sc->anon_creds); | ||
150 | 160 | ||
151 | #ifdef ENABLE_SRP | 161 | #ifdef ENABLE_SRP |
152 | if (ctxt->sc->srp_tpasswd_conf_file != NULL | 162 | if (ctxt->sc->srp_tpasswd_conf_file != NULL |
153 | && ctxt->sc->srp_tpasswd_file != NULL) { | 163 | && ctxt->sc->srp_tpasswd_file != NULL) { |
154 | gnutls_credentials_set(session, GNUTLS_CRD_SRP, | 164 | gnutls_credentials_set(session, GNUTLS_CRD_SRP, |
155 | ctxt->sc->srp_creds); | 165 | ctxt->sc->srp_creds); |
156 | } | 166 | } |
157 | #endif | 167 | #endif |
158 | 168 | ||
159 | /* update the priorities - to avoid negotiating a ciphersuite that is not | 169 | /* update the priorities - to avoid negotiating a ciphersuite that is not |
160 | * enabled on this virtual server. Note that here we ignore the version | 170 | * enabled on this virtual server. Note that here we ignore the version |
161 | * negotiation. | 171 | * negotiation. |
162 | */ | 172 | */ |
163 | ret = gnutls_priority_set(session, ctxt->sc->priorities); | 173 | ret = gnutls_priority_set(session, ctxt->sc->priorities); |
164 | /* actually it shouldn't fail since we have checked at startup */ | 174 | /* actually it shouldn't fail since we have checked at startup */ |
165 | if (ret < 0) | 175 | if (ret < 0) |
166 | return ret; | 176 | return ret; |
167 | 177 | ||
168 | /* If both certificate types are not present disallow them from | 178 | /* If both certificate types are not present disallow them from |
169 | * being negotiated. | 179 | * being negotiated. |
170 | */ | 180 | */ |
171 | if (ctxt->sc->certs_x509[0] != NULL && ctxt->sc->cert_pgp == NULL) { | 181 | if (ctxt->sc->certs_x509[0] != NULL && ctxt->sc->cert_pgp == NULL) { |
172 | cprio[0] = GNUTLS_CRT_X509; | 182 | cprio[0] = GNUTLS_CRT_X509; |
173 | cprio[1] = 0; | 183 | cprio[1] = 0; |
174 | gnutls_certificate_type_set_priority( session, cprio); | 184 | gnutls_certificate_type_set_priority(session, cprio); |
175 | } else if (ctxt->sc->cert_pgp != NULL && ctxt->sc->certs_x509[0]==NULL) { | 185 | } else if (ctxt->sc->cert_pgp != NULL |
176 | cprio[0] = GNUTLS_CRT_OPENPGP; | 186 | && ctxt->sc->certs_x509[0] == NULL) { |
177 | cprio[1] = 0; | 187 | cprio[0] = GNUTLS_CRT_OPENPGP; |
178 | gnutls_certificate_type_set_priority( session, cprio); | 188 | cprio[1] = 0; |
179 | } | 189 | gnutls_certificate_type_set_priority(session, cprio); |
180 | 190 | } | |
181 | return 0; | 191 | |
192 | return 0; | ||
182 | } | 193 | } |
183 | 194 | ||
184 | static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st * ret) | 195 | static int cert_retrieve_fn(gnutls_session_t session, gnutls_retr_st * ret) |
185 | { | 196 | { |
186 | mgs_handle_t *ctxt; | 197 | mgs_handle_t *ctxt; |
198 | |||
199 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | ||
200 | ctxt = gnutls_transport_get_ptr(session); | ||
187 | 201 | ||
188 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 202 | if (ctxt == NULL) |
189 | ctxt = gnutls_transport_get_ptr(session); | 203 | return GNUTLS_E_INTERNAL_ERROR; |
190 | 204 | ||
191 | if (ctxt == NULL) | 205 | if (gnutls_certificate_type_get(session) == GNUTLS_CRT_X509) { |
192 | return GNUTLS_E_INTERNAL_ERROR; | 206 | ret->type = GNUTLS_CRT_X509; |
207 | ret->ncerts = ctxt->sc->certs_x509_num; | ||
208 | ret->deinit_all = 0; | ||
193 | 209 | ||
194 | if (gnutls_certificate_type_get( session) == GNUTLS_CRT_X509) { | 210 | ret->cert.x509 = ctxt->sc->certs_x509; |
195 | ret->type = GNUTLS_CRT_X509; | 211 | ret->key.x509 = ctxt->sc->privkey_x509; |
196 | ret->ncerts = ctxt->sc->certs_x509_num; | ||
197 | ret->deinit_all = 0; | ||
198 | 212 | ||
199 | ret->cert.x509 = ctxt->sc->certs_x509; | 213 | return 0; |
200 | ret->key.x509 = ctxt->sc->privkey_x509; | 214 | } else if (gnutls_certificate_type_get(session) == |
201 | 215 | GNUTLS_CRT_OPENPGP) { | |
202 | return 0; | 216 | ret->type = GNUTLS_CRT_OPENPGP; |
203 | } else if (gnutls_certificate_type_get( session) == GNUTLS_CRT_OPENPGP) { | 217 | ret->ncerts = 1; |
204 | ret->type = GNUTLS_CRT_OPENPGP; | 218 | ret->deinit_all = 0; |
205 | ret->ncerts = 1; | ||
206 | ret->deinit_all = 0; | ||
207 | 219 | ||
208 | ret->cert.pgp = ctxt->sc->cert_pgp; | 220 | ret->cert.pgp = ctxt->sc->cert_pgp; |
209 | ret->key.pgp = ctxt->sc->privkey_pgp; | 221 | ret->key.pgp = ctxt->sc->privkey_pgp; |
210 | 222 | ||
211 | return 0; | 223 | return 0; |
212 | |||
213 | } | ||
214 | 224 | ||
215 | return GNUTLS_E_INTERNAL_ERROR; | 225 | } |
226 | |||
227 | return GNUTLS_E_INTERNAL_ERROR; | ||
216 | } | 228 | } |
217 | 229 | ||
218 | /* 2048-bit group parameters from SRP specification */ | 230 | /* 2048-bit group parameters from SRP specification */ |
@@ -233,78 +245,81 @@ const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n" | |||
233 | static int read_crt_cn(server_rec * s, apr_pool_t * p, | 245 | static int read_crt_cn(server_rec * s, apr_pool_t * p, |
234 | gnutls_x509_crt_t cert, char **cert_cn) | 246 | gnutls_x509_crt_t cert, char **cert_cn) |
235 | { | 247 | { |
236 | int rv = 0, i; | 248 | int rv = 0, i; |
237 | size_t data_len; | 249 | size_t data_len; |
238 | |||
239 | 250 | ||
240 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | ||
241 | *cert_cn = NULL; | ||
242 | 251 | ||
243 | data_len = 0; | 252 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
244 | rv = gnutls_x509_crt_get_dn_by_oid(cert, | 253 | *cert_cn = NULL; |
245 | GNUTLS_OID_X520_COMMON_NAME, | ||
246 | 0, 0, NULL, &data_len); | ||
247 | 254 | ||
248 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { | 255 | data_len = 0; |
249 | *cert_cn = apr_palloc(p, data_len); | ||
250 | rv = gnutls_x509_crt_get_dn_by_oid(cert, | 256 | rv = gnutls_x509_crt_get_dn_by_oid(cert, |
251 | GNUTLS_OID_X520_COMMON_NAME, 0, | 257 | GNUTLS_OID_X520_COMMON_NAME, |
252 | 0, *cert_cn, &data_len); | 258 | 0, 0, NULL, &data_len); |
253 | } else { /* No CN return subject alternative name */ | 259 | |
254 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, | 260 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { |
255 | "No common name found in certificate for '%s:%d'. Looking for subject alternative name...", | 261 | *cert_cn = apr_palloc(p, data_len); |
256 | s->server_hostname, s->port); | 262 | rv = gnutls_x509_crt_get_dn_by_oid(cert, |
257 | rv = 0; | 263 | GNUTLS_OID_X520_COMMON_NAME, |
258 | /* read subject alternative name */ | 264 | 0, 0, *cert_cn, |
259 | for (i = 0; !(rv < 0); i++) { | 265 | &data_len); |
260 | data_len = 0; | 266 | } else { /* No CN return subject alternative name */ |
261 | rv = gnutls_x509_crt_get_subject_alt_name(cert, i, | 267 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, |
262 | NULL, &data_len, | 268 | "No common name found in certificate for '%s:%d'. Looking for subject alternative name...", |
263 | NULL); | 269 | s->server_hostname, s->port); |
264 | 270 | rv = 0; | |
265 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { | 271 | /* read subject alternative name */ |
266 | /* FIXME: not very efficient. What if we have several alt names | 272 | for (i = 0; !(rv < 0); i++) { |
267 | * before DNSName? | 273 | data_len = 0; |
268 | */ | 274 | rv = gnutls_x509_crt_get_subject_alt_name(cert, i, |
269 | *cert_cn = apr_palloc(p, data_len + 1); | 275 | NULL, |
270 | 276 | &data_len, | |
271 | rv = gnutls_x509_crt_get_subject_alt_name(cert, i, | 277 | NULL); |
272 | *cert_cn, | 278 | |
273 | &data_len, NULL); | 279 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER |
274 | (*cert_cn)[data_len] = 0; | 280 | && data_len > 1) { |
275 | 281 | /* FIXME: not very efficient. What if we have several alt names | |
276 | if (rv == GNUTLS_SAN_DNSNAME) | 282 | * before DNSName? |
277 | break; | 283 | */ |
278 | } | 284 | *cert_cn = apr_palloc(p, data_len + 1); |
285 | |||
286 | rv = gnutls_x509_crt_get_subject_alt_name | ||
287 | (cert, i, *cert_cn, &data_len, NULL); | ||
288 | (*cert_cn)[data_len] = 0; | ||
289 | |||
290 | if (rv == GNUTLS_SAN_DNSNAME) | ||
291 | break; | ||
292 | } | ||
293 | } | ||
279 | } | 294 | } |
280 | } | ||
281 | 295 | ||
282 | return rv; | 296 | return rv; |
283 | } | 297 | } |
284 | 298 | ||
285 | static int read_pgpcrt_cn(server_rec * s, apr_pool_t * p, | 299 | static int read_pgpcrt_cn(server_rec * s, apr_pool_t * p, |
286 | gnutls_openpgp_crt_t cert, char **cert_cn) | 300 | gnutls_openpgp_crt_t cert, char **cert_cn) |
287 | { | 301 | { |
288 | int rv = 0; | 302 | int rv = 0; |
289 | size_t data_len; | 303 | size_t data_len; |
290 | 304 | ||
291 | 305 | ||
292 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 306 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
293 | *cert_cn = NULL; | 307 | *cert_cn = NULL; |
294 | 308 | ||
295 | data_len = 0; | 309 | data_len = 0; |
296 | rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len); | 310 | rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len); |
297 | 311 | ||
298 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { | 312 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { |
299 | *cert_cn = apr_palloc(p, data_len); | 313 | *cert_cn = apr_palloc(p, data_len); |
300 | rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn, &data_len); | 314 | rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn, |
301 | } else { /* No CN return subject alternative name */ | 315 | &data_len); |
302 | ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, | 316 | } else { /* No CN return subject alternative name */ |
303 | "No name found in PGP certificate for '%s:%d'.", | 317 | ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, |
304 | s->server_hostname, s->port); | 318 | "No name found in PGP certificate for '%s:%d'.", |
305 | } | 319 | s->server_hostname, s->port); |
320 | } | ||
306 | 321 | ||
307 | return rv; | 322 | return rv; |
308 | } | 323 | } |
309 | 324 | ||
310 | 325 | ||
@@ -312,27 +327,27 @@ int | |||
312 | mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, | 327 | mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, |
313 | apr_pool_t * ptemp, server_rec * base_server) | 328 | apr_pool_t * ptemp, server_rec * base_server) |
314 | { | 329 | { |
315 | int rv; | 330 | int rv; |
316 | server_rec *s; | 331 | server_rec *s; |
317 | gnutls_dh_params_t dh_params = NULL; | 332 | gnutls_dh_params_t dh_params = NULL; |
318 | gnutls_rsa_params_t rsa_params = NULL; | 333 | gnutls_rsa_params_t rsa_params = NULL; |
319 | mgs_srvconf_rec *sc; | 334 | mgs_srvconf_rec *sc; |
320 | mgs_srvconf_rec *sc_base; | 335 | mgs_srvconf_rec *sc_base; |
321 | void *data = NULL; | 336 | void *data = NULL; |
322 | int first_run = 0; | 337 | int first_run = 0; |
323 | const char *userdata_key = "mgs_init"; | 338 | const char *userdata_key = "mgs_init"; |
324 | 339 | ||
325 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 340 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
326 | apr_pool_userdata_get(&data, userdata_key, base_server->process->pool); | 341 | apr_pool_userdata_get(&data, userdata_key, |
327 | if (data == NULL) { | ||
328 | first_run = 1; | ||
329 | apr_pool_userdata_set((const void *) 1, userdata_key, | ||
330 | apr_pool_cleanup_null, | ||
331 | base_server->process->pool); | 342 | base_server->process->pool); |
332 | } | 343 | if (data == NULL) { |
344 | first_run = 1; | ||
345 | apr_pool_userdata_set((const void *) 1, userdata_key, | ||
346 | apr_pool_cleanup_null, | ||
347 | base_server->process->pool); | ||
348 | } | ||
333 | 349 | ||
334 | 350 | ||
335 | { | ||
336 | s = base_server; | 351 | s = base_server; |
337 | sc_base = | 352 | sc_base = |
338 | (mgs_srvconf_rec *) ap_get_module_config(s->module_config, | 353 | (mgs_srvconf_rec *) ap_get_module_config(s->module_config, |
@@ -341,545 +356,568 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, | |||
341 | gnutls_dh_params_init(&dh_params); | 356 | gnutls_dh_params_init(&dh_params); |
342 | 357 | ||
343 | if (sc_base->dh_params == NULL) { | 358 | if (sc_base->dh_params == NULL) { |
344 | gnutls_datum pdata = { (void *) static_dh_params, sizeof(static_dh_params) }; | 359 | gnutls_datum pdata = { |
345 | /* loading defaults */ | 360 | (void *) static_dh_params, |
346 | rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, | 361 | sizeof(static_dh_params) |
347 | GNUTLS_X509_FMT_PEM); | 362 | }; |
348 | 363 | /* loading defaults */ | |
349 | if (rv < 0) { | 364 | rv = gnutls_dh_params_import_pkcs3(dh_params, &pdata, |
350 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, | 365 | GNUTLS_X509_FMT_PEM); |
351 | "GnuTLS: Unable to load DH Params: (%d) %s", | 366 | |
352 | rv, gnutls_strerror(rv)); | 367 | if (rv < 0) { |
353 | exit(rv); | 368 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, |
354 | } | 369 | "GnuTLS: Unable to load DH Params: (%d) %s", |
355 | } else dh_params = sc_base->dh_params; | 370 | rv, gnutls_strerror(rv)); |
356 | 371 | exit(rv); | |
357 | if (sc_base->rsa_params != NULL) | 372 | } |
358 | rsa_params = sc_base->rsa_params; | 373 | } else |
374 | dh_params = sc_base->dh_params; | ||
375 | |||
376 | if (sc_base->rsa_params != NULL) | ||
377 | rsa_params = sc_base->rsa_params; | ||
359 | 378 | ||
360 | /* else not an error but RSA-EXPORT ciphersuites are not available | 379 | /* else not an error but RSA-EXPORT ciphersuites are not available |
361 | */ | 380 | */ |
362 | 381 | ||
363 | rv = mgs_cache_post_config(p, s, sc_base); | 382 | rv = mgs_cache_post_config(p, s, sc_base); |
364 | if (rv != 0) { | 383 | if (rv != 0) { |
365 | ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, | 384 | ap_log_error(APLOG_MARK, APLOG_STARTUP, rv, s, |
366 | "GnuTLS: Post Config for GnuTLSCache Failed." | 385 | "GnuTLS: Post Config for GnuTLSCache Failed." |
367 | " Shutting Down."); | 386 | " Shutting Down."); |
368 | exit(-1); | 387 | exit(-1); |
369 | } | 388 | } |
370 | 389 | ||
371 | for (s = base_server; s; s = s->next) { | 390 | for (s = base_server; s; s = s->next) { |
372 | void *load = NULL; | 391 | void *load = NULL; |
373 | sc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, | 392 | sc = (mgs_srvconf_rec *) |
374 | &gnutls_module); | 393 | ap_get_module_config(s->module_config, &gnutls_module); |
375 | sc->cache_type = sc_base->cache_type; | 394 | sc->cache_type = sc_base->cache_type; |
376 | sc->cache_config = sc_base->cache_config; | 395 | sc->cache_config = sc_base->cache_config; |
377 | 396 | ||
378 | /* Check if the priorities have been set */ | 397 | /* Check if the priorities have been set */ |
379 | if (sc->priorities == NULL && sc->enabled == GNUTLS_ENABLED_TRUE) { | 398 | if (sc->priorities == NULL |
380 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, | 399 | && sc->enabled == GNUTLS_ENABLED_TRUE) { |
381 | "GnuTLS: Host '%s:%d' is missing the GnuTLSPriorities directive!", | 400 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, |
382 | s->server_hostname, s->port); | 401 | "GnuTLS: Host '%s:%d' is missing the GnuTLSPriorities directive!", |
383 | exit(-1); | 402 | s->server_hostname, s->port); |
384 | } | 403 | exit(-1); |
385 | 404 | } | |
386 | /* Check if DH or RSA params have been set per host */ | 405 | |
387 | if (sc->rsa_params != NULL) | 406 | /* Check if DH or RSA params have been set per host */ |
388 | load = sc->rsa_params; | 407 | if (sc->rsa_params != NULL) |
389 | else if (rsa_params) load = rsa_params; | 408 | load = sc->rsa_params; |
390 | 409 | else if (rsa_params) | |
391 | if (load != NULL) | 410 | load = rsa_params; |
392 | gnutls_certificate_set_rsa_export_params(sc->certs, load); | 411 | |
393 | 412 | if (load != NULL) | |
394 | 413 | gnutls_certificate_set_rsa_export_params(sc->certs, | |
395 | load = NULL; | 414 | load); |
396 | if (sc->dh_params != NULL) | 415 | |
397 | load = sc->dh_params; | 416 | |
398 | else if (dh_params) load = dh_params; | 417 | load = NULL; |
399 | 418 | if (sc->dh_params != NULL) | |
400 | if (load != NULL) { /* not needed but anyway */ | 419 | load = sc->dh_params; |
401 | gnutls_certificate_set_dh_params(sc->certs, load); | 420 | else if (dh_params) |
402 | gnutls_anon_set_server_dh_params(sc->anon_creds, load); | 421 | load = dh_params; |
403 | } | 422 | |
404 | 423 | if (load != NULL) { /* not needed but anyway */ | |
405 | gnutls_certificate_server_set_retrieve_function(sc->certs, | 424 | gnutls_certificate_set_dh_params(sc->certs, load); |
406 | cert_retrieve_fn); | 425 | gnutls_anon_set_server_dh_params(sc->anon_creds, |
426 | load); | ||
427 | } | ||
428 | |||
429 | gnutls_certificate_server_set_retrieve_function(sc->certs, | ||
430 | cert_retrieve_fn); | ||
407 | 431 | ||
408 | #ifdef ENABLE_SRP | 432 | #ifdef ENABLE_SRP |
409 | if (sc->srp_tpasswd_conf_file != NULL | 433 | if (sc->srp_tpasswd_conf_file != NULL |
410 | && sc->srp_tpasswd_file != NULL) { | 434 | && sc->srp_tpasswd_file != NULL) { |
411 | rv = gnutls_srp_set_server_credentials_file(sc->srp_creds, | 435 | rv = gnutls_srp_set_server_credentials_file |
412 | sc-> | 436 | (sc->srp_creds, sc->srp_tpasswd_file, |
413 | srp_tpasswd_file, | 437 | sc->srp_tpasswd_conf_file); |
414 | sc-> | 438 | |
415 | srp_tpasswd_conf_file); | 439 | if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { |
416 | 440 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, | |
417 | if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { | 441 | s, |
418 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, | 442 | "[GnuTLS] - Host '%s:%d' is missing a " |
419 | "[GnuTLS] - Host '%s:%d' is missing a " | 443 | "SRP password or conf File!", |
420 | "SRP password or conf File!", | 444 | s->server_hostname, s->port); |
421 | s->server_hostname, s->port); | 445 | exit(-1); |
422 | exit(-1); | 446 | } |
423 | } | 447 | } |
424 | } | ||
425 | #endif | 448 | #endif |
426 | 449 | ||
427 | if (sc->certs_x509[0] == NULL && | 450 | if (sc->certs_x509[0] == NULL && |
428 | sc->cert_pgp == NULL && | 451 | sc->cert_pgp == NULL && |
429 | sc->enabled == GNUTLS_ENABLED_TRUE) { | 452 | sc->enabled == GNUTLS_ENABLED_TRUE) { |
430 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, | 453 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, |
431 | "[GnuTLS] - Host '%s:%d' is missing a " | 454 | "[GnuTLS] - Host '%s:%d' is missing a " |
432 | "Certificate File!", s->server_hostname, | 455 | "Certificate File!", |
433 | s->port); | 456 | s->server_hostname, s->port); |
434 | exit(-1); | 457 | exit(-1); |
435 | } | 458 | } |
436 | |||
437 | if (sc->enabled == GNUTLS_ENABLED_TRUE && | ||
438 | ((sc->certs_x509[0] != NULL && sc->privkey_x509 == NULL) || | ||
439 | (sc->cert_pgp != NULL && sc->privkey_pgp == NULL))) { | ||
440 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, | ||
441 | "[GnuTLS] - Host '%s:%d' is missing a " | ||
442 | "Private Key File!", | ||
443 | s->server_hostname, s->port); | ||
444 | exit(-1); | ||
445 | } | ||
446 | 459 | ||
447 | if (sc->enabled == GNUTLS_ENABLED_TRUE) { | 460 | if (sc->enabled == GNUTLS_ENABLED_TRUE && |
448 | rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn); | 461 | ((sc->certs_x509[0] != NULL |
449 | if (rv < 0 && sc->cert_pgp != NULL) /* try openpgp certificate */ | 462 | && sc->privkey_x509 == NULL) || (sc->cert_pgp != NULL |
450 | rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn); | 463 | && sc->privkey_pgp |
464 | == NULL))) { | ||
465 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, | ||
466 | "[GnuTLS] - Host '%s:%d' is missing a " | ||
467 | "Private Key File!", | ||
468 | s->server_hostname, s->port); | ||
469 | exit(-1); | ||
470 | } | ||
451 | 471 | ||
452 | if (rv < 0) { | 472 | if (sc->enabled == GNUTLS_ENABLED_TRUE) { |
453 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, | 473 | rv = read_crt_cn(s, p, sc->certs_x509[0], |
454 | "[GnuTLS] - Cannot find a certificate for host '%s:%d'!", | 474 | &sc->cert_cn); |
455 | s->server_hostname, s->port); | 475 | if (rv < 0 && sc->cert_pgp != NULL) /* try openpgp certificate */ |
456 | sc->cert_cn = NULL; | 476 | rv = read_pgpcrt_cn(s, p, sc->cert_pgp, |
457 | continue; | 477 | &sc->cert_cn); |
478 | |||
479 | if (rv < 0) { | ||
480 | ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, | ||
481 | s, | ||
482 | "[GnuTLS] - Cannot find a certificate for host '%s:%d'!", | ||
483 | s->server_hostname, s->port); | ||
484 | sc->cert_cn = NULL; | ||
485 | continue; | ||
486 | } | ||
458 | } | 487 | } |
459 | } | ||
460 | } | 488 | } |
461 | } | ||
462 | 489 | ||
463 | ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION); | ||
464 | 490 | ||
465 | return OK; | 491 | ap_add_version_component(p, "mod_gnutls/" MOD_GNUTLS_VERSION); |
492 | |||
493 | return OK; | ||
466 | } | 494 | } |
467 | 495 | ||
468 | void mgs_hook_child_init(apr_pool_t * p, server_rec * s) | 496 | void mgs_hook_child_init(apr_pool_t * p, server_rec * s) |
469 | { | 497 | { |
470 | apr_status_t rv = APR_SUCCESS; | 498 | apr_status_t rv = APR_SUCCESS; |
471 | mgs_srvconf_rec *sc = ap_get_module_config(s->module_config, | 499 | mgs_srvconf_rec *sc = ap_get_module_config(s->module_config, |
472 | &gnutls_module); | 500 | &gnutls_module); |
473 | 501 | ||
474 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 502 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
475 | if (sc->cache_type != mgs_cache_none) { | 503 | if (sc->cache_type != mgs_cache_none) { |
476 | rv = mgs_cache_child_init(p, s, sc); | 504 | rv = mgs_cache_child_init(p, s, sc); |
477 | if (rv != APR_SUCCESS) { | 505 | if (rv != APR_SUCCESS) { |
478 | ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, | 506 | ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, |
479 | "[GnuTLS] - Failed to run Cache Init"); | 507 | "[GnuTLS] - Failed to run Cache Init"); |
508 | } | ||
509 | } else { | ||
510 | ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, | ||
511 | "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache"); | ||
480 | } | 512 | } |
481 | } else { | ||
482 | ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, | ||
483 | "[GnuTLS] - No Cache Configured. Hint: GnuTLSCache"); | ||
484 | } | ||
485 | } | 513 | } |
486 | 514 | ||
487 | const char *mgs_hook_http_scheme(const request_rec * r) | 515 | const char *mgs_hook_http_scheme(const request_rec * r) |
488 | { | 516 | { |
489 | mgs_srvconf_rec *sc; | 517 | mgs_srvconf_rec *sc; |
490 | |||
491 | if (r == NULL) | ||
492 | return NULL; | ||
493 | |||
494 | sc = | ||
495 | (mgs_srvconf_rec *) ap_get_module_config(r->server->module_config, | ||
496 | &gnutls_module); | ||
497 | |||
498 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | ||
499 | if (sc->enabled == GNUTLS_ENABLED_FALSE) { | ||
500 | return NULL; | ||
501 | } | ||
502 | 518 | ||
503 | return "https"; | 519 | if (r == NULL) |
520 | return NULL; | ||
521 | |||
522 | sc = (mgs_srvconf_rec *) ap_get_module_config(r-> | ||
523 | server->module_config, | ||
524 | &gnutls_module); | ||
525 | |||
526 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | ||
527 | if (sc->enabled == GNUTLS_ENABLED_FALSE) { | ||
528 | return NULL; | ||
529 | } | ||
530 | |||
531 | return "https"; | ||
504 | } | 532 | } |
505 | 533 | ||
506 | apr_port_t mgs_hook_default_port(const request_rec * r) | 534 | apr_port_t mgs_hook_default_port(const request_rec * r) |
507 | { | 535 | { |
508 | mgs_srvconf_rec *sc; | 536 | mgs_srvconf_rec *sc; |
509 | 537 | ||
510 | if (r == NULL) | 538 | if (r == NULL) |
511 | return 0; | 539 | return 0; |
512 | 540 | ||
513 | sc = | 541 | sc = (mgs_srvconf_rec *) ap_get_module_config(r-> |
514 | (mgs_srvconf_rec *) ap_get_module_config(r->server->module_config, | 542 | server->module_config, |
515 | &gnutls_module); | 543 | &gnutls_module); |
516 | 544 | ||
517 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 545 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
518 | if (sc->enabled == GNUTLS_ENABLED_FALSE) { | 546 | if (sc->enabled == GNUTLS_ENABLED_FALSE) { |
519 | return 0; | 547 | return 0; |
520 | } | 548 | } |
521 | 549 | ||
522 | return 443; | 550 | return 443; |
523 | } | 551 | } |
524 | 552 | ||
525 | #define MAX_HOST_LEN 255 | 553 | #define MAX_HOST_LEN 255 |
526 | 554 | ||
527 | #if USING_2_1_RECENT | 555 | #if USING_2_1_RECENT |
528 | typedef struct { | 556 | typedef struct { |
529 | mgs_handle_t *ctxt; | 557 | mgs_handle_t *ctxt; |
530 | mgs_srvconf_rec *sc; | 558 | mgs_srvconf_rec *sc; |
531 | const char *sni_name; | 559 | const char *sni_name; |
532 | } vhost_cb_rec; | 560 | } vhost_cb_rec; |
533 | 561 | ||
534 | static int vhost_cb(void *baton, conn_rec * conn, server_rec * s) | 562 | static int vhost_cb(void *baton, conn_rec * conn, server_rec * s) |
535 | { | 563 | { |
536 | mgs_srvconf_rec *tsc; | 564 | mgs_srvconf_rec *tsc; |
537 | vhost_cb_rec *x = baton; | 565 | vhost_cb_rec *x = baton; |
538 | 566 | ||
539 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 567 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
540 | tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, | 568 | tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, |
541 | &gnutls_module); | 569 | &gnutls_module); |
542 | 570 | ||
543 | if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) { | 571 | if (tsc->enabled != GNUTLS_ENABLED_TRUE || tsc->cert_cn == NULL) { |
544 | return 0; | 572 | return 0; |
545 | } | 573 | } |
546 | 574 | ||
547 | /* The CN can contain a * -- this will match those too. */ | 575 | /* The CN can contain a * -- this will match those too. */ |
548 | if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) { | 576 | if (ap_strcasecmp_match(x->sni_name, tsc->cert_cn) == 0) { |
549 | /* found a match */ | 577 | /* found a match */ |
550 | #if MOD_GNUTLS_DEBUG | 578 | #if MOD_GNUTLS_DEBUG |
551 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | 579 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, |
552 | x->ctxt->c->base_server, | 580 | x->ctxt->c->base_server, |
553 | "GnuTLS: Virtual Host CB: " | 581 | "GnuTLS: Virtual Host CB: " |
554 | "'%s' == '%s'", tsc->cert_cn, x->sni_name); | 582 | "'%s' == '%s'", tsc->cert_cn, x->sni_name); |
555 | #endif | 583 | #endif |
556 | /* Because we actually change the server used here, we need to reset | 584 | /* Because we actually change the server used here, we need to reset |
557 | * things like ClientVerify. | 585 | * things like ClientVerify. |
558 | */ | 586 | */ |
559 | x->sc = tsc; | 587 | x->sc = tsc; |
560 | /* Shit. Crap. Dammit. We *really* should rehandshake here, as our | 588 | /* Shit. Crap. Dammit. We *really* should rehandshake here, as our |
561 | * certificate structure *should* change when the server changes. | 589 | * certificate structure *should* change when the server changes. |
562 | * acccckkkkkk. | 590 | * acccckkkkkk. |
563 | */ | 591 | */ |
564 | return 1; | 592 | return 1; |
565 | } else { | 593 | } else { |
566 | #if MOD_GNUTLS_DEBUG | 594 | #if MOD_GNUTLS_DEBUG |
567 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | 595 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, |
568 | x->ctxt->c->base_server, | 596 | x->ctxt->c->base_server, |
569 | "GnuTLS: Virtual Host CB: " | 597 | "GnuTLS: Virtual Host CB: " |
570 | "'%s' != '%s'", tsc->cert_cn, x->sni_name); | 598 | "'%s' != '%s'", tsc->cert_cn, x->sni_name); |
571 | #endif | 599 | #endif |
572 | 600 | ||
573 | } | 601 | } |
574 | return 0; | 602 | return 0; |
575 | } | 603 | } |
576 | #endif | 604 | #endif |
577 | 605 | ||
578 | mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session) | 606 | mgs_srvconf_rec *mgs_find_sni_server(gnutls_session_t session) |
579 | { | 607 | { |
580 | int rv; | 608 | int rv; |
581 | unsigned int sni_type; | 609 | unsigned int sni_type; |
582 | size_t data_len = MAX_HOST_LEN; | 610 | size_t data_len = MAX_HOST_LEN; |
583 | char sni_name[MAX_HOST_LEN]; | 611 | char sni_name[MAX_HOST_LEN]; |
584 | mgs_handle_t *ctxt; | 612 | mgs_handle_t *ctxt; |
585 | #if USING_2_1_RECENT | 613 | #if USING_2_1_RECENT |
586 | vhost_cb_rec cbx; | 614 | vhost_cb_rec cbx; |
587 | #else | 615 | #else |
588 | server_rec *s; | 616 | server_rec *s; |
589 | mgs_srvconf_rec *tsc; | 617 | mgs_srvconf_rec *tsc; |
590 | #endif | 618 | #endif |
591 | 619 | ||
592 | if (session == NULL) | 620 | if (session == NULL) |
593 | return NULL; | 621 | return NULL; |
594 | 622 | ||
595 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 623 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
596 | ctxt = gnutls_transport_get_ptr(session); | 624 | ctxt = gnutls_transport_get_ptr(session); |
597 | 625 | ||
598 | rv = gnutls_server_name_get(ctxt->session, sni_name, | 626 | rv = gnutls_server_name_get(ctxt->session, sni_name, |
599 | &data_len, &sni_type, 0); | 627 | &data_len, &sni_type, 0); |
600 | 628 | ||
601 | if (rv != 0) { | 629 | if (rv != 0) { |
602 | return NULL; | 630 | return NULL; |
603 | } | 631 | } |
604 | 632 | ||
605 | if (sni_type != GNUTLS_NAME_DNS) { | 633 | if (sni_type != GNUTLS_NAME_DNS) { |
606 | ap_log_error(APLOG_MARK, APLOG_CRIT, 0, | 634 | ap_log_error(APLOG_MARK, APLOG_CRIT, 0, |
607 | ctxt->c->base_server, | 635 | ctxt->c->base_server, |
608 | "GnuTLS: Unknown type '%d' for SNI: " | 636 | "GnuTLS: Unknown type '%d' for SNI: " |
609 | "'%s'", sni_type, sni_name); | 637 | "'%s'", sni_type, sni_name); |
610 | return NULL; | 638 | return NULL; |
611 | } | 639 | } |
612 | 640 | ||
613 | /** | 641 | /** |
614 | * Code in the Core already sets up the c->base_server as the base | 642 | * Code in the Core already sets up the c->base_server as the base |
615 | * for this IP/Port combo. Trust that the core did the 'right' thing. | 643 | * for this IP/Port combo. Trust that the core did the 'right' thing. |
616 | */ | 644 | */ |
617 | #if USING_2_1_RECENT | 645 | #if USING_2_1_RECENT |
618 | cbx.ctxt = ctxt; | 646 | cbx.ctxt = ctxt; |
619 | cbx.sc = NULL; | 647 | cbx.sc = NULL; |
620 | cbx.sni_name = sni_name; | 648 | cbx.sni_name = sni_name; |
621 | |||
622 | rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx); | ||
623 | if (rv == 1) { | ||
624 | return cbx.sc; | ||
625 | } | ||
626 | #else | ||
627 | for (s = ap_server_conf; s; s = s->next) { | ||
628 | 649 | ||
629 | tsc = (mgs_srvconf_rec *) ap_get_module_config(s->module_config, | 650 | rv = ap_vhost_iterate_given_conn(ctxt->c, vhost_cb, &cbx); |
630 | &gnutls_module); | 651 | if (rv == 1) { |
631 | if (tsc->enabled != GNUTLS_ENABLED_TRUE) { | 652 | return cbx.sc; |
632 | continue; | ||
633 | } | 653 | } |
654 | #else | ||
655 | for (s = ap_server_conf; s; s = s->next) { | ||
656 | |||
657 | tsc = | ||
658 | (mgs_srvconf_rec *) | ||
659 | ap_get_module_config(s->module_config, &gnutls_module); | ||
660 | if (tsc->enabled != GNUTLS_ENABLED_TRUE) { | ||
661 | continue; | ||
662 | } | ||
634 | #if MOD_GNUTLS_DEBUG | 663 | #if MOD_GNUTLS_DEBUG |
635 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | 664 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, |
636 | ctxt->c->base_server, | 665 | ctxt->c->base_server, |
637 | "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X sc: 0x%08X", | 666 | "GnuTLS: sni-x509 cn: %s/%d pk: %s s: 0x%08X s->n: 0x%08X sc: 0x%08X", |
638 | tsc->cert_cn, rv, | 667 | tsc->cert_cn, rv, |
639 | gnutls_pk_algorithm_get_name | 668 | gnutls_pk_algorithm_get_name |
640 | (gnutls_x509_privkey_get_pk_algorithm | 669 | (gnutls_x509_privkey_get_pk_algorithm |
641 | (ctxt->sc->privkey_x509)), (unsigned int) s, | 670 | (ctxt->sc->privkey_x509)), (unsigned int) s, |
642 | (unsigned int) s->next, (unsigned int) tsc); | 671 | (unsigned int) s->next, (unsigned int) tsc); |
643 | #endif | 672 | #endif |
644 | /* The CN can contain a * -- this will match those too. */ | 673 | /* The CN can contain a * -- this will match those too. */ |
645 | if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) { | 674 | if (ap_strcasecmp_match(sni_name, tsc->cert_cn) == 0) { |
646 | #if MOD_GNUTLS_DEBUG | 675 | #if MOD_GNUTLS_DEBUG |
647 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, | 676 | ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, |
648 | ctxt->c->base_server, | 677 | ctxt->c->base_server, |
649 | "GnuTLS: Virtual Host: " | 678 | "GnuTLS: Virtual Host: " |
650 | "'%s' == '%s'", tsc->cert_cn, sni_name); | 679 | "'%s' == '%s'", tsc->cert_cn, |
680 | sni_name); | ||
651 | #endif | 681 | #endif |
652 | return tsc; | 682 | return tsc; |
683 | } | ||
653 | } | 684 | } |
654 | } | ||
655 | #endif | 685 | #endif |
656 | return NULL; | 686 | return NULL; |
657 | } | 687 | } |
658 | 688 | ||
659 | 689 | ||
660 | static const int protocol_priority[] = { | 690 | static const int protocol_priority[] = { |
661 | GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 | 691 | GNUTLS_TLS1_1, GNUTLS_TLS1_0, GNUTLS_SSL3, 0 |
662 | }; | 692 | }; |
663 | 693 | ||
664 | 694 | ||
665 | static mgs_handle_t *create_gnutls_handle(apr_pool_t * pool, conn_rec * c) | 695 | static mgs_handle_t *create_gnutls_handle(apr_pool_t * pool, conn_rec * c) |
666 | { | 696 | { |
667 | mgs_handle_t *ctxt; | 697 | mgs_handle_t *ctxt; |
668 | mgs_srvconf_rec *sc = | 698 | mgs_srvconf_rec *sc = |
669 | (mgs_srvconf_rec *) ap_get_module_config(c->base_server-> | 699 | (mgs_srvconf_rec *) ap_get_module_config(c->base_server-> |
670 | module_config, | 700 | module_config, |
671 | &gnutls_module); | 701 | &gnutls_module); |
672 | 702 | ||
673 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 703 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
674 | ctxt = apr_pcalloc(pool, sizeof(*ctxt)); | 704 | ctxt = apr_pcalloc(pool, sizeof(*ctxt)); |
675 | ctxt->c = c; | 705 | ctxt->c = c; |
676 | ctxt->sc = sc; | 706 | ctxt->sc = sc; |
677 | ctxt->status = 0; | 707 | ctxt->status = 0; |
678 | 708 | ||
679 | ctxt->input_rc = APR_SUCCESS; | 709 | ctxt->input_rc = APR_SUCCESS; |
680 | ctxt->input_bb = apr_brigade_create(c->pool, c->bucket_alloc); | 710 | ctxt->input_bb = apr_brigade_create(c->pool, c->bucket_alloc); |
681 | ctxt->input_cbuf.length = 0; | 711 | ctxt->input_cbuf.length = 0; |
682 | 712 | ||
683 | ctxt->output_rc = APR_SUCCESS; | 713 | ctxt->output_rc = APR_SUCCESS; |
684 | ctxt->output_bb = apr_brigade_create(c->pool, c->bucket_alloc); | 714 | ctxt->output_bb = apr_brigade_create(c->pool, c->bucket_alloc); |
685 | ctxt->output_blen = 0; | 715 | ctxt->output_blen = 0; |
686 | ctxt->output_length = 0; | 716 | ctxt->output_length = 0; |
687 | 717 | ||
688 | gnutls_init(&ctxt->session, GNUTLS_SERVER); | 718 | gnutls_init(&ctxt->session, GNUTLS_SERVER); |
689 | if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0) | 719 | if (session_ticket_key.data != NULL && ctxt->sc->tickets != 0) |
690 | gnutls_session_ticket_enable_server(ctxt->session, &session_ticket_key); | 720 | gnutls_session_ticket_enable_server(ctxt->session, |
691 | 721 | &session_ticket_key); | |
692 | /* because we don't set any default priorities here (we set later at | 722 | |
693 | * the user hello callback) we need to at least set this in order for | 723 | /* because we don't set any default priorities here (we set later at |
694 | * gnutls to be able to read packets. | 724 | * the user hello callback) we need to at least set this in order for |
695 | */ | 725 | * gnutls to be able to read packets. |
696 | gnutls_protocol_set_priority(ctxt->session, protocol_priority); | 726 | */ |
727 | gnutls_protocol_set_priority(ctxt->session, protocol_priority); | ||
697 | 728 | ||
698 | gnutls_handshake_set_post_client_hello_function(ctxt->session, | 729 | gnutls_handshake_set_post_client_hello_function(ctxt->session, |
699 | mgs_select_virtual_server_cb); | 730 | mgs_select_virtual_server_cb); |
700 | 731 | ||
701 | mgs_cache_session_init(ctxt); | 732 | mgs_cache_session_init(ctxt); |
702 | 733 | ||
703 | return ctxt; | 734 | return ctxt; |
704 | } | 735 | } |
705 | 736 | ||
706 | int mgs_hook_pre_connection(conn_rec * c, void *csd) | 737 | int mgs_hook_pre_connection(conn_rec * c, void *csd) |
707 | { | 738 | { |
708 | mgs_handle_t *ctxt; | 739 | mgs_handle_t *ctxt; |
709 | mgs_srvconf_rec *sc; | 740 | mgs_srvconf_rec *sc; |
710 | 741 | ||
711 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 742 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
712 | 743 | ||
713 | if (c == NULL) | 744 | if (c == NULL) |
714 | return DECLINED; | 745 | return DECLINED; |
715 | |||
716 | sc = | ||
717 | (mgs_srvconf_rec *) ap_get_module_config(c->base_server-> | ||
718 | module_config, | ||
719 | &gnutls_module); | ||
720 | |||
721 | if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) { | ||
722 | return DECLINED; | ||
723 | } | ||
724 | 746 | ||
725 | if(c->remote_addr->hostname) | 747 | sc = (mgs_srvconf_rec *) ap_get_module_config(c->base_server-> |
726 | /* Connection initiated by Apache (mod_proxy) => ignore */ | 748 | module_config, |
727 | return OK; | 749 | &gnutls_module); |
728 | 750 | ||
729 | ctxt = create_gnutls_handle(c->pool, c); | 751 | if (!(sc && (sc->enabled == GNUTLS_ENABLED_TRUE))) { |
752 | return DECLINED; | ||
753 | } | ||
754 | |||
755 | if (c->remote_addr->hostname) | ||
756 | /* Connection initiated by Apache (mod_proxy) => ignore */ | ||
757 | return OK; | ||
758 | |||
759 | ctxt = create_gnutls_handle(c->pool, c); | ||
730 | 760 | ||
731 | ap_set_module_config(c->conn_config, &gnutls_module, ctxt); | 761 | ap_set_module_config(c->conn_config, &gnutls_module, ctxt); |
732 | 762 | ||
733 | gnutls_transport_set_pull_function(ctxt->session, mgs_transport_read); | 763 | gnutls_transport_set_pull_function(ctxt->session, |
734 | gnutls_transport_set_push_function(ctxt->session, mgs_transport_write); | 764 | mgs_transport_read); |
735 | gnutls_transport_set_ptr(ctxt->session, ctxt); | 765 | gnutls_transport_set_push_function(ctxt->session, |
766 | mgs_transport_write); | ||
767 | gnutls_transport_set_ptr(ctxt->session, ctxt); | ||
736 | 768 | ||
737 | ctxt->input_filter = | 769 | ctxt->input_filter = |
738 | ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c); | 770 | ap_add_input_filter(GNUTLS_INPUT_FILTER_NAME, ctxt, NULL, c); |
739 | ctxt->output_filter = | 771 | ctxt->output_filter = |
740 | ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c); | 772 | ap_add_output_filter(GNUTLS_OUTPUT_FILTER_NAME, ctxt, NULL, c); |
741 | 773 | ||
742 | return OK; | 774 | return OK; |
743 | } | 775 | } |
744 | 776 | ||
745 | int mgs_hook_fixups(request_rec * r) | 777 | int mgs_hook_fixups(request_rec * r) |
746 | { | 778 | { |
747 | unsigned char sbuf[GNUTLS_MAX_SESSION_ID]; | 779 | unsigned char sbuf[GNUTLS_MAX_SESSION_ID]; |
748 | char buf[AP_IOBUFSIZE]; | 780 | char buf[AP_IOBUFSIZE]; |
749 | const char *tmp; | 781 | const char *tmp; |
750 | size_t len; | 782 | size_t len; |
751 | mgs_handle_t *ctxt; | 783 | mgs_handle_t *ctxt; |
752 | int rv = OK; | 784 | int rv = OK; |
753 | 785 | ||
754 | if (r == NULL) | 786 | if (r == NULL) |
755 | return DECLINED; | 787 | return DECLINED; |
756 | 788 | ||
757 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 789 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
758 | apr_table_t *env = r->subprocess_env; | 790 | apr_table_t *env = r->subprocess_env; |
759 | 791 | ||
760 | ctxt = | 792 | ctxt = |
761 | ap_get_module_config(r->connection->conn_config, &gnutls_module); | 793 | ap_get_module_config(r->connection->conn_config, |
794 | &gnutls_module); | ||
762 | 795 | ||
763 | if (!ctxt || ctxt->session == NULL) { | 796 | if (!ctxt || ctxt->session == NULL) { |
764 | return DECLINED; | 797 | return DECLINED; |
765 | } | 798 | } |
766 | 799 | ||
767 | apr_table_setn(env, "HTTPS", "on"); | 800 | apr_table_setn(env, "HTTPS", "on"); |
768 | 801 | ||
769 | apr_table_setn(env, "SSL_VERSION_LIBRARY", | 802 | apr_table_setn(env, "SSL_VERSION_LIBRARY", |
770 | "GnuTLS/" LIBGNUTLS_VERSION); | 803 | "GnuTLS/" LIBGNUTLS_VERSION); |
771 | apr_table_setn(env, "SSL_VERSION_INTERFACE", | 804 | apr_table_setn(env, "SSL_VERSION_INTERFACE", |
772 | "mod_gnutls/" MOD_GNUTLS_VERSION); | 805 | "mod_gnutls/" MOD_GNUTLS_VERSION); |
773 | 806 | ||
774 | apr_table_setn(env, "SSL_PROTOCOL", | 807 | apr_table_setn(env, "SSL_PROTOCOL", |
775 | gnutls_protocol_get_name(gnutls_protocol_get_version | 808 | gnutls_protocol_get_name(gnutls_protocol_get_version |
776 | (ctxt->session))); | 809 | (ctxt->session))); |
777 | 810 | ||
778 | /* should have been called SSL_CIPHERSUITE instead */ | 811 | /* should have been called SSL_CIPHERSUITE instead */ |
779 | apr_table_setn(env, "SSL_CIPHER", | 812 | apr_table_setn(env, "SSL_CIPHER", |
780 | gnutls_cipher_suite_get_name(gnutls_kx_get | 813 | gnutls_cipher_suite_get_name(gnutls_kx_get |
781 | (ctxt->session), | 814 | (ctxt->session), |
782 | gnutls_cipher_get(ctxt-> | 815 | gnutls_cipher_get |
783 | session), | 816 | (ctxt->session), |
784 | gnutls_mac_get(ctxt-> | 817 | gnutls_mac_get |
785 | session))); | 818 | (ctxt->session))); |
786 | 819 | ||
787 | apr_table_setn(env, "SSL_COMPRESS_METHOD", | 820 | apr_table_setn(env, "SSL_COMPRESS_METHOD", |
788 | gnutls_compression_get_name(gnutls_compression_get | 821 | gnutls_compression_get_name(gnutls_compression_get |
789 | (ctxt->session))); | 822 | (ctxt->session))); |
790 | 823 | ||
791 | #ifdef ENABLE_SRP | 824 | #ifdef ENABLE_SRP |
792 | tmp = gnutls_srp_server_get_username(ctxt->session); | 825 | tmp = gnutls_srp_server_get_username(ctxt->session); |
793 | apr_table_setn(env, "SSL_SRP_USER", (tmp!=NULL)?tmp:""); | 826 | apr_table_setn(env, "SSL_SRP_USER", (tmp != NULL) ? tmp : ""); |
794 | #endif | 827 | #endif |
795 | 828 | ||
796 | if (apr_table_get(env, "SSL_CLIENT_VERIFY") == NULL) | 829 | if (apr_table_get(env, "SSL_CLIENT_VERIFY") == NULL) |
797 | apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE"); | 830 | apr_table_setn(env, "SSL_CLIENT_VERIFY", "NONE"); |
798 | 831 | ||
799 | unsigned int key_size = | 832 | unsigned int key_size = |
800 | 8 * gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session)); | 833 | 8 * |
801 | tmp = apr_psprintf(r->pool, "%u", key_size); | 834 | gnutls_cipher_get_key_size(gnutls_cipher_get(ctxt->session)); |
835 | tmp = apr_psprintf(r->pool, "%u", key_size); | ||
802 | 836 | ||
803 | apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp); | 837 | apr_table_setn(env, "SSL_CIPHER_USEKEYSIZE", tmp); |
804 | 838 | ||
805 | apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp); | 839 | apr_table_setn(env, "SSL_CIPHER_ALGKEYSIZE", tmp); |
806 | 840 | ||
807 | apr_table_setn(env, "SSL_CIPHER_EXPORT", | 841 | apr_table_setn(env, "SSL_CIPHER_EXPORT", |
808 | (key_size <= 40) ? "true" : "false"); | 842 | (key_size <= 40) ? "true" : "false"); |
809 | 843 | ||
810 | len = sizeof(sbuf); | 844 | len = sizeof(sbuf); |
811 | gnutls_session_get_id(ctxt->session, sbuf, &len); | 845 | gnutls_session_get_id(ctxt->session, sbuf, &len); |
812 | tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); | 846 | tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); |
813 | apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp)); | 847 | apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp)); |
814 | 848 | ||
815 | if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) | 849 | if (gnutls_certificate_type_get(ctxt->session) == GNUTLS_CRT_X509) |
816 | mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0, | 850 | mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0, |
817 | ctxt->sc->export_certificates_enabled); | 851 | ctxt-> |
818 | else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) | 852 | sc->export_certificates_enabled); |
819 | mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0, | 853 | else if (gnutls_certificate_type_get(ctxt->session) == |
820 | ctxt->sc->export_certificates_enabled); | 854 | GNUTLS_CRT_OPENPGP) |
855 | mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0, | ||
856 | ctxt-> | ||
857 | sc->export_certificates_enabled); | ||
821 | 858 | ||
822 | return rv; | 859 | return rv; |
823 | } | 860 | } |
824 | 861 | ||
825 | int mgs_hook_authz(request_rec * r) | 862 | int mgs_hook_authz(request_rec * r) |
826 | { | 863 | { |
827 | int rv; | 864 | int rv; |
828 | mgs_handle_t *ctxt; | 865 | mgs_handle_t *ctxt; |
829 | mgs_dirconf_rec *dc; | 866 | mgs_dirconf_rec *dc; |
830 | 867 | ||
831 | if (r == NULL) | 868 | if (r == NULL) |
832 | return DECLINED; | 869 | return DECLINED; |
833 | 870 | ||
834 | dc = ap_get_module_config(r->per_dir_config, | 871 | dc = ap_get_module_config(r->per_dir_config, &gnutls_module); |
835 | &gnutls_module); | 872 | |
836 | 873 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | |
837 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 874 | ctxt = |
838 | ctxt = | 875 | ap_get_module_config(r->connection->conn_config, |
839 | ap_get_module_config(r->connection->conn_config, &gnutls_module); | 876 | &gnutls_module); |
840 | 877 | ||
841 | if (!ctxt || ctxt->session == NULL) { | 878 | if (!ctxt || ctxt->session == NULL) { |
842 | return DECLINED; | 879 | return DECLINED; |
843 | } | 880 | } |
844 | 881 | ||
845 | if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) { | 882 | if (dc->client_verify_mode == GNUTLS_CERT_IGNORE) { |
846 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, | 883 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
847 | "GnuTLS: Directory set to Ignore Client Certificate!"); | 884 | "GnuTLS: Directory set to Ignore Client Certificate!"); |
848 | } else { | 885 | } else { |
849 | if (ctxt->sc->client_verify_mode < dc->client_verify_mode) { | 886 | if (ctxt->sc->client_verify_mode < dc->client_verify_mode) { |
850 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, | 887 | ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, |
851 | "GnuTLS: Attempting to rehandshake with peer. %d %d", | 888 | "GnuTLS: Attempting to rehandshake with peer. %d %d", |
852 | ctxt->sc->client_verify_mode, | 889 | ctxt->sc->client_verify_mode, |
853 | dc->client_verify_mode); | 890 | dc->client_verify_mode); |
854 | 891 | ||
855 | /* If we already have a client certificate, there's no point in | 892 | /* If we already have a client certificate, there's no point in |
856 | * re-handshaking... */ | 893 | * re-handshaking... */ |
857 | rv = mgs_cert_verify(r, ctxt); | 894 | rv = mgs_cert_verify(r, ctxt); |
858 | if (rv != DECLINED && rv != HTTP_FORBIDDEN) | 895 | if (rv != DECLINED && rv != HTTP_FORBIDDEN) |
859 | return rv; | 896 | return rv; |
860 | 897 | ||
861 | gnutls_certificate_server_set_request(ctxt->session, | 898 | gnutls_certificate_server_set_request |
862 | dc->client_verify_mode); | 899 | (ctxt->session, dc->client_verify_mode); |
863 | 900 | ||
864 | if (mgs_rehandshake(ctxt) != 0) { | 901 | if (mgs_rehandshake(ctxt) != 0) { |
865 | return HTTP_FORBIDDEN; | 902 | return HTTP_FORBIDDEN; |
866 | } | 903 | } |
867 | } else if (ctxt->sc->client_verify_mode == GNUTLS_CERT_IGNORE) { | 904 | } else if (ctxt->sc->client_verify_mode == |
905 | GNUTLS_CERT_IGNORE) { | ||
868 | #if MOD_GNUTLS_DEBUG | 906 | #if MOD_GNUTLS_DEBUG |
869 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, | 907 | ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, |
870 | "GnuTLS: Peer is set to IGNORE"); | 908 | "GnuTLS: Peer is set to IGNORE"); |
871 | #endif | 909 | #endif |
872 | return DECLINED; | 910 | return DECLINED; |
873 | } | 911 | } |
874 | rv = mgs_cert_verify(r, ctxt); | 912 | rv = mgs_cert_verify(r, ctxt); |
875 | if (rv != DECLINED && | 913 | if (rv != DECLINED && |
876 | (rv != HTTP_FORBIDDEN || | 914 | (rv != HTTP_FORBIDDEN || |
877 | dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) { | 915 | dc->client_verify_mode == GNUTLS_CERT_REQUIRE)) { |
878 | return rv; | 916 | return rv; |
917 | } | ||
879 | } | 918 | } |
880 | } | ||
881 | 919 | ||
882 | return DECLINED; | 920 | return DECLINED; |
883 | } | 921 | } |
884 | 922 | ||
885 | /* variables that are not sent by default: | 923 | /* variables that are not sent by default: |
@@ -895,359 +933,413 @@ static void | |||
895 | mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, | 933 | mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, |
896 | int export_certificates_enabled) | 934 | int export_certificates_enabled) |
897 | { | 935 | { |
898 | unsigned char sbuf[64]; /* buffer to hold serials */ | 936 | unsigned char sbuf[64]; /* buffer to hold serials */ |
899 | char buf[AP_IOBUFSIZE]; | 937 | char buf[AP_IOBUFSIZE]; |
900 | const char *tmp; | 938 | const char *tmp; |
901 | char *tmp2; | 939 | char *tmp2; |
902 | size_t len; | 940 | size_t len; |
903 | int ret, i; | 941 | int ret, i; |
904 | 942 | ||
905 | if (r == NULL) | 943 | if (r == NULL) |
906 | return; | 944 | return; |
907 | 945 | ||
908 | apr_table_t *env = r->subprocess_env; | 946 | apr_table_t *env = r->subprocess_env; |
909 | 947 | ||
910 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); | 948 | _gnutls_log(debug_log_fp, "%s: %d\n", __func__, __LINE__); |
911 | if (export_certificates_enabled != 0) { | 949 | if (export_certificates_enabled != 0) { |
912 | char cert_buf[10 * 1024]; | 950 | char cert_buf[10 * 1024]; |
913 | len = sizeof(cert_buf); | 951 | len = sizeof(cert_buf); |
914 | 952 | ||
915 | if (gnutls_x509_crt_export | 953 | if (gnutls_x509_crt_export |
916 | (cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0) | 954 | (cert, GNUTLS_X509_FMT_PEM, cert_buf, &len) >= 0) |
917 | apr_table_setn(env, | 955 | apr_table_setn(env, |
918 | apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL), | 956 | apr_pstrcat(r->pool, MGS_SIDE, |
919 | apr_pstrmemdup(r->pool, cert_buf, len)); | 957 | "_CERT", NULL), |
920 | 958 | apr_pstrmemdup(r->pool, cert_buf, | |
921 | } | 959 | len)); |
922 | 960 | ||
923 | len = sizeof(buf); | 961 | } |
924 | gnutls_x509_crt_get_dn(cert, buf, &len); | 962 | |
925 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_S_DN", NULL), | 963 | len = sizeof(buf); |
926 | apr_pstrmemdup(r->pool, buf, len)); | 964 | gnutls_x509_crt_get_dn(cert, buf, &len); |
927 | 965 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_S_DN", NULL), | |
928 | len = sizeof(buf); | 966 | apr_pstrmemdup(r->pool, buf, len)); |
929 | gnutls_x509_crt_get_issuer_dn(cert, buf, &len); | 967 | |
930 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_I_DN", NULL), | 968 | len = sizeof(buf); |
931 | apr_pstrmemdup(r->pool, buf, len)); | 969 | gnutls_x509_crt_get_issuer_dn(cert, buf, &len); |
932 | 970 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_I_DN", NULL), | |
933 | len = sizeof(sbuf); | 971 | apr_pstrmemdup(r->pool, buf, len)); |
934 | gnutls_x509_crt_get_serial(cert, sbuf, &len); | 972 | |
935 | tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); | 973 | len = sizeof(sbuf); |
936 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL), | 974 | gnutls_x509_crt_get_serial(cert, sbuf, &len); |
937 | apr_pstrdup(r->pool, tmp)); | 975 | tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); |
938 | |||
939 | ret = gnutls_x509_crt_get_version(cert); | ||
940 | if (ret > 0) | ||
941 | apr_table_setn(env, | 976 | apr_table_setn(env, |
942 | apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL), | 977 | apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL), |
943 | apr_psprintf(r->pool, "%u", ret)); | 978 | apr_pstrdup(r->pool, tmp)); |
944 | 979 | ||
945 | apr_table_setn(env, | 980 | ret = gnutls_x509_crt_get_version(cert); |
946 | apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), "X.509"); | 981 | if (ret > 0) |
947 | |||
948 | tmp = | ||
949 | mgs_time2sz(gnutls_x509_crt_get_expiration_time | ||
950 | (cert), buf, sizeof(buf)); | ||
951 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL), | ||
952 | apr_pstrdup(r->pool, tmp)); | ||
953 | |||
954 | tmp = | ||
955 | mgs_time2sz(gnutls_x509_crt_get_activation_time | ||
956 | (cert), buf, sizeof(buf)); | ||
957 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL), | ||
958 | apr_pstrdup(r->pool, tmp)); | ||
959 | |||
960 | ret = gnutls_x509_crt_get_signature_algorithm(cert); | ||
961 | if (ret >= 0) { | ||
962 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", NULL), | ||
963 | gnutls_sign_algorithm_get_name(ret)); | ||
964 | } | ||
965 | |||
966 | ret = gnutls_x509_crt_get_pk_algorithm(cert, NULL); | ||
967 | if (ret >= 0) { | ||
968 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL), | ||
969 | gnutls_pk_algorithm_get_name(ret)); | ||
970 | } | ||
971 | |||
972 | /* export all the alternative names (DNS, RFC822 and URI) */ | ||
973 | for (i = 0; !(ret < 0); i++) { | ||
974 | len = 0; | ||
975 | ret = gnutls_x509_crt_get_subject_alt_name(cert, i, | ||
976 | NULL, &len, NULL); | ||
977 | |||
978 | if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && len > 1) { | ||
979 | tmp2 = apr_palloc(r->pool, len + 1); | ||
980 | |||
981 | ret = | ||
982 | gnutls_x509_crt_get_subject_alt_name(cert, i, tmp2, &len, | ||
983 | NULL); | ||
984 | tmp2[len] = 0; | ||
985 | |||
986 | if (ret == GNUTLS_SAN_DNSNAME) { | ||
987 | apr_table_setn(env, | ||
988 | apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i), | ||
989 | apr_psprintf(r->pool, "DNSNAME:%s", tmp2)); | ||
990 | } else if (ret == GNUTLS_SAN_RFC822NAME) { | ||
991 | apr_table_setn(env, | 982 | apr_table_setn(env, |
992 | apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i), | 983 | apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", |
993 | apr_psprintf(r->pool, "RFC822NAME:%s", tmp2)); | 984 | NULL), apr_psprintf(r->pool, |
994 | } else if (ret == GNUTLS_SAN_URI) { | 985 | "%u", ret)); |
986 | |||
987 | apr_table_setn(env, | ||
988 | apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), | ||
989 | "X.509"); | ||
990 | |||
991 | tmp = | ||
992 | mgs_time2sz(gnutls_x509_crt_get_expiration_time | ||
993 | (cert), buf, sizeof(buf)); | ||
994 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL), | ||
995 | apr_pstrdup(r->pool, tmp)); | ||
996 | |||
997 | tmp = | ||
998 | mgs_time2sz(gnutls_x509_crt_get_activation_time | ||
999 | (cert), buf, sizeof(buf)); | ||
1000 | apr_table_setn(env, | ||
1001 | apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL), | ||
1002 | apr_pstrdup(r->pool, tmp)); | ||
1003 | |||
1004 | ret = gnutls_x509_crt_get_signature_algorithm(cert); | ||
1005 | if (ret >= 0) { | ||
995 | apr_table_setn(env, | 1006 | apr_table_setn(env, |
996 | apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i), | 1007 | apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", |
997 | apr_psprintf(r->pool, "URI:%s", tmp2)); | 1008 | NULL), |
998 | } else { | 1009 | gnutls_sign_algorithm_get_name(ret)); |
1010 | } | ||
1011 | |||
1012 | ret = gnutls_x509_crt_get_pk_algorithm(cert, NULL); | ||
1013 | if (ret >= 0) { | ||
999 | apr_table_setn(env, | 1014 | apr_table_setn(env, |
1000 | apr_psprintf(r->pool, "%s_S_AN%u", MGS_SIDE, i), | 1015 | apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", |
1001 | "UNSUPPORTED"); | 1016 | NULL), |
1002 | } | 1017 | gnutls_pk_algorithm_get_name(ret)); |
1018 | } | ||
1019 | |||
1020 | /* export all the alternative names (DNS, RFC822 and URI) */ | ||
1021 | for (i = 0; !(ret < 0); i++) { | ||
1022 | len = 0; | ||
1023 | ret = gnutls_x509_crt_get_subject_alt_name(cert, i, | ||
1024 | NULL, &len, | ||
1025 | NULL); | ||
1026 | |||
1027 | if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && len > 1) { | ||
1028 | tmp2 = apr_palloc(r->pool, len + 1); | ||
1029 | |||
1030 | ret = | ||
1031 | gnutls_x509_crt_get_subject_alt_name(cert, i, | ||
1032 | tmp2, | ||
1033 | &len, | ||
1034 | NULL); | ||
1035 | tmp2[len] = 0; | ||
1036 | |||
1037 | if (ret == GNUTLS_SAN_DNSNAME) { | ||
1038 | apr_table_setn(env, | ||
1039 | apr_psprintf(r->pool, | ||
1040 | "%s_S_AN%u", | ||
1041 | MGS_SIDE, i), | ||
1042 | apr_psprintf(r->pool, | ||
1043 | "DNSNAME:%s", | ||
1044 | tmp2)); | ||
1045 | } else if (ret == GNUTLS_SAN_RFC822NAME) { | ||
1046 | apr_table_setn(env, | ||
1047 | apr_psprintf(r->pool, | ||
1048 | "%s_S_AN%u", | ||
1049 | MGS_SIDE, i), | ||
1050 | apr_psprintf(r->pool, | ||
1051 | "RFC822NAME:%s", | ||
1052 | tmp2)); | ||
1053 | } else if (ret == GNUTLS_SAN_URI) { | ||
1054 | apr_table_setn(env, | ||
1055 | apr_psprintf(r->pool, | ||
1056 | "%s_S_AN%u", | ||
1057 | MGS_SIDE, i), | ||
1058 | apr_psprintf(r->pool, | ||
1059 | "URI:%s", | ||
1060 | tmp2)); | ||
1061 | } else { | ||
1062 | apr_table_setn(env, | ||
1063 | apr_psprintf(r->pool, | ||
1064 | "%s_S_AN%u", | ||
1065 | MGS_SIDE, i), | ||
1066 | "UNSUPPORTED"); | ||
1067 | } | ||
1068 | } | ||
1003 | } |