Apache HTTPD
mod_session_crypto.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "mod_session.h"
18#include "apu_version.h"
19#include "apr_base64.h" /* for apr_base64_decode et al */
20#include "apr_lib.h"
21#include "apr_md5.h"
22#include "apr_strings.h"
23#include "http_log.h"
24#include "http_core.h"
25
26#if APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION < 4
27
28#error session_crypto_module requires APU v1.4.0 or later
29
30#elif APU_HAVE_CRYPTO == 0
31
32#error Crypto support must be enabled in APR
33
34#else
35
36#include "apr_crypto.h" /* for apr_*_crypt et al */
37
38#define CRYPTO_KEY "session_crypto_context"
39
40module AP_MODULE_DECLARE_DATA session_crypto_module;
41
45typedef struct {
48 const char *cipher;
49 int cipher_set;
51
55typedef struct {
56 const char *library;
57 const char *params;
58 int library_set;
60
61/* Wrappers around apr_siphash24() and apr_crypto_equals(),
62 * available in APU-1.6/APR-2.0 only.
63 */
64#if APU_MAJOR_VERSION > 1 || (APU_MAJOR_VERSION == 1 && APU_MINOR_VERSION >= 6)
65
66#include "apr_siphash.h"
67
68#define AP_SIPHASH_DSIZE APR_SIPHASH_DSIZE
69#define AP_SIPHASH_KSIZE APR_SIPHASH_KSIZE
70#define ap_siphash24_auth apr_siphash24_auth
71
72#define ap_crypto_equals apr_crypto_equals
73
74#else
75
76#define AP_SIPHASH_DSIZE 8
77#define AP_SIPHASH_KSIZE 16
78
79#define ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
80
81#define U8TO64_LE(p) \
82 (((apr_uint64_t)((p)[0]) ) | \
83 ((apr_uint64_t)((p)[1]) << 8) | \
84 ((apr_uint64_t)((p)[2]) << 16) | \
85 ((apr_uint64_t)((p)[3]) << 24) | \
86 ((apr_uint64_t)((p)[4]) << 32) | \
87 ((apr_uint64_t)((p)[5]) << 40) | \
88 ((apr_uint64_t)((p)[6]) << 48) | \
89 ((apr_uint64_t)((p)[7]) << 56))
90
91#define U64TO8_LE(p, v) \
92do { \
93 (p)[0] = (unsigned char)((v) ); \
94 (p)[1] = (unsigned char)((v) >> 8); \
95 (p)[2] = (unsigned char)((v) >> 16); \
96 (p)[3] = (unsigned char)((v) >> 24); \
97 (p)[4] = (unsigned char)((v) >> 32); \
98 (p)[5] = (unsigned char)((v) >> 40); \
99 (p)[6] = (unsigned char)((v) >> 48); \
100 (p)[7] = (unsigned char)((v) >> 56); \
101} while (0)
102
103#define SIPROUND() \
104do { \
105 v0 += v1; v1=ROTL64(v1,13); v1 ^= v0; v0=ROTL64(v0,32); \
106 v2 += v3; v3=ROTL64(v3,16); v3 ^= v2; \
107 v0 += v3; v3=ROTL64(v3,21); v3 ^= v0; \
108 v2 += v1; v1=ROTL64(v1,17); v1 ^= v2; v2=ROTL64(v2,32); \
109} while(0)
110
111static apr_uint64_t ap_siphash24(const void *src, apr_size_t len,
112 const unsigned char key[AP_SIPHASH_KSIZE])
113{
114 const unsigned char *ptr, *end;
115 apr_uint64_t v0, v1, v2, v3, m;
117 unsigned int rem;
118
119 k0 = U8TO64_LE(key + 0);
120 k1 = U8TO64_LE(key + 8);
121 v3 = k1 ^ (apr_uint64_t)0x7465646279746573ULL;
122 v2 = k0 ^ (apr_uint64_t)0x6c7967656e657261ULL;
123 v1 = k1 ^ (apr_uint64_t)0x646f72616e646f6dULL;
124 v0 = k0 ^ (apr_uint64_t)0x736f6d6570736575ULL;
125
126 rem = (unsigned int)(len & 0x7);
127 for (ptr = src, end = ptr + len - rem; ptr < end; ptr += 8) {
128 m = U8TO64_LE(ptr);
129 v3 ^= m;
130 SIPROUND();
131 SIPROUND();
132 v0 ^= m;
133 }
134 m = (apr_uint64_t)(len & 0xff) << 56;
135 switch (rem) {
136 case 7: m |= (apr_uint64_t)ptr[6] << 48;
137 case 6: m |= (apr_uint64_t)ptr[5] << 40;
138 case 5: m |= (apr_uint64_t)ptr[4] << 32;
139 case 4: m |= (apr_uint64_t)ptr[3] << 24;
140 case 3: m |= (apr_uint64_t)ptr[2] << 16;
141 case 2: m |= (apr_uint64_t)ptr[1] << 8;
142 case 1: m |= (apr_uint64_t)ptr[0];
143 case 0: break;
144 }
145 v3 ^= m;
146 SIPROUND();
147 SIPROUND();
148 v0 ^= m;
149
150 v2 ^= 0xff;
151 SIPROUND();
152 SIPROUND();
153 SIPROUND();
154 SIPROUND();
155
156 return v0 ^ v1 ^ v2 ^ v3;
157}
158
159static void ap_siphash24_auth(unsigned char out[AP_SIPHASH_DSIZE],
160 const void *src, apr_size_t len,
161 const unsigned char key[AP_SIPHASH_KSIZE])
162{
164 h = ap_siphash24(src, len, key);
165 U64TO8_LE(out, h);
166}
167
168static int ap_crypto_equals(const void *buf1, const void *buf2,
170{
171 const unsigned char *p1 = buf1;
172 const unsigned char *p2 = buf2;
173 unsigned char diff = 0;
175
176 for (i = 0; i < size; ++i) {
177 diff |= p1[i] ^ p2[i];
178 }
179
180 return 1 & ((diff - 1) >> 8);
181}
182
183#endif
184
185static void compute_auth(const void *src, apr_size_t len,
186 const char *passphrase, apr_size_t passlen,
187 unsigned char auth[AP_SIPHASH_DSIZE])
188{
189 unsigned char key[APR_MD5_DIGESTSIZE];
190
191 /* XXX: if we had a way to get the raw bytes from an apr_crypto_key_t
192 * we could use them directly (not available in APR-1.5.x).
193 * MD5 is 128bit too, so use it to get a suitable siphash key
194 * from the passphrase.
195 */
197
198 ap_siphash24_auth(auth, src, len, key);
199}
200
209{
212
214 if (APR_SUCCESS != res) {
216 "no ciphers returned by APR. "
217 "session encryption not possible");
218 return res;
219 }
220
222 if (!(*cipher)) {
224 const void *key;
226 int sum = 0;
227 int offset = 0;
228 char *options = NULL;
229
232 sum += klen + 2;
233 }
236 if (!options) {
237 options = apr_palloc(r->pool, sum + 1);
238 }
239 else {
240 options[offset++] = ',';
241 options[offset++] = ' ';
242 }
243 strncpy(options + offset, key, klen);
244 offset += klen;
245 }
246 options[offset] = 0;
247
249 "cipher '%s' not recognised by crypto driver. "
250 "session encryption not possible, options: %s", dconf->cipher, options);
251
252 return APR_EGENERAL;
253 }
254
255 return APR_SUCCESS;
256}
257
264 session_crypto_dir_conf *dconf, const char *in, char **out)
265{
268 apr_size_t ivSize = 0;
270 unsigned char *encrypt = NULL;
271 unsigned char *combined = NULL;
273 char *base64;
275 const unsigned char *iv = NULL;
278 const char *passphrase;
280
281 /* use a uuid as a salt value, and prepend it to our result */
283 res = crypt_init(r, f, &cipher, dconf);
284 if (res != APR_SUCCESS) {
285 return res;
286 }
287
288 /* encrypt using the first passphrase in the list */
289 passphrase = APR_ARRAY_IDX(dconf->passphrases, 0, const char *);
290 passlen = strlen(passphrase);
292 (unsigned char *) (&salt), sizeof(apr_uuid_t),
293 *cipher, APR_MODE_CBC, 1, 4096, f, r->pool);
296 "failure generating key from passphrase");
297 }
300 "padding is not supported for cipher");
301 }
304 "the key type is not known");
305 }
306 if (APR_SUCCESS != res) {
308 "encryption could not be configured.");
309 return res;
310 }
311
313 if (APR_SUCCESS != res) {
315 "apr_crypto_block_encrypt_init failed");
316 return res;
317 }
318
319 /* encrypt the given string */
321 (const unsigned char *)in, strlen(in),
322 block);
323 if (APR_SUCCESS != res) {
325 "apr_crypto_block_encrypt failed");
326 return res;
327 }
329 if (APR_SUCCESS != res) {
331 "apr_crypto_block_encrypt_finish failed");
332 return res;
333 }
334 encryptlen += tlen;
335
336 /* prepend the salt and the iv to the result (keep room for the MAC) */
343 /* authenticate the whole salt+IV+ciphertext with a leading MAC */
346
347 /* base64 encode the result (APR handles the trailing '\0') */
350 *out = base64;
351
352 return res;
353
354}
355
362 session_crypto_dir_conf *dconf, const char *in, char **out)
363{
366 apr_size_t ivSize = 0;
368 unsigned char *decrypted = NULL;
371 char *decoded;
374 unsigned char auth[AP_SIPHASH_DSIZE];
375 int i = 0;
376
377 /* strip base64 from the string */
380 decoded[decodedlen] = '\0';
381
382 /* sanity check - decoded too short? */
383 if (decodedlen < (AP_SIPHASH_DSIZE + sizeof(apr_uuid_t))) {
385 "too short to decrypt, aborting");
386 return APR_ECRYPT;
387 }
388
389 res = crypt_init(r, f, &cipher, dconf);
390 if (res != APR_SUCCESS) {
391 return res;
392 }
393
394 res = APR_ECRYPT; /* in case we exhaust all passphrases */
395
396 /* try each passphrase in turn */
397 for (; i < dconf->passphrases->nelts; i++) {
398 const char *passphrase = APR_ARRAY_IDX(dconf->passphrases, i, char *);
399 apr_size_t passlen = strlen(passphrase);
401 unsigned char *slider = (unsigned char *)decoded + AP_SIPHASH_DSIZE;
402
403 /* Verify authentication of the whole salt+IV+ciphertext by computing
404 * the MAC and comparing it (timing safe) with the one in the payload.
405 */
409 "auth does not match, skipping");
410 continue;
411 }
412
413 /* encrypt using the first passphrase in the list */
415 slider, sizeof(apr_uuid_t),
416 *cipher, APR_MODE_CBC, 1, 4096,
417 f, r->pool);
420 "failure generating key from passphrase");
421 continue;
422 }
423 else if (APR_STATUS_IS_EPADDING(res)) {
425 "padding is not supported for cipher");
426 continue;
427 }
428 else if (APR_STATUS_IS_EKEYTYPE(res)) {
430 "the key type is not known");
431 continue;
432 }
433 else if (APR_SUCCESS != res) {
435 "encryption could not be configured.");
436 continue;
437 }
438
439 /* sanity check - decoded too short? */
440 if (len < (sizeof(apr_uuid_t) + ivSize)) {
442 "too short to decrypt, skipping");
443 res = APR_ECRYPT;
444 continue;
445 }
446
447 /* bypass the salt at the start of the decoded block */
448 slider += sizeof(apr_uuid_t);
449 len -= sizeof(apr_uuid_t);
450
452 r->pool);
453 if (APR_SUCCESS != res) {
455 "apr_crypto_block_decrypt_init failed");
456 continue;
457 }
458
459 /* bypass the iv at the start of the decoded block */
460 slider += ivSize;
461 len -= ivSize;
462
463 /* decrypt the given string */
465 slider, len, block);
466 if (res) {
468 "apr_crypto_block_decrypt failed");
469 continue;
470 }
471 *out = (char *) decrypted;
472
474 if (APR_SUCCESS != res) {
476 "apr_crypto_block_decrypt_finish failed");
477 continue;
478 }
481
482 break;
483 }
484
485 if (APR_SUCCESS != res) {
487 "decryption failed");
488 }
489
490 return res;
491
492}
493
501{
502
503 char *encoded = NULL;
505 const apr_crypto_t *f = NULL;
508
509 if (dconf->passphrases_set && z->encoded && *z->encoded) {
511 res = encrypt_string(r, f, dconf, z->encoded, &encoded);
512 if (res != OK) {
514 "encrypt session failed");
515 return res;
516 }
517 z->encoded = encoded;
518 }
519
520 return OK;
521
522}
523
531 session_rec * z)
532{
533
534 char *encoded = NULL;
536 const apr_crypto_t *f = NULL;
539
540 if ((dconf->passphrases_set) && z->encoded && *z->encoded) {
542 r->server->process->pconf);
543 res = decrypt_string(r, f, dconf, z->encoded, &encoded);
544 if (res != APR_SUCCESS) {
546 "decrypt session failed, wrong passphrase?");
547 return res;
548 }
549 z->encoded = encoded;
550 }
551
552 return OK;
553
554}
555
560 apr_pool_t *ptemp, server_rec *s)
561{
564
565 session_crypto_conf *conf = ap_get_module_config(s->module_config,
567
568 /* session_crypto_init() will be called twice. Don't bother
569 * going through all of the initialization on the first call
570 * because it will just be thrown away.*/
572 return OK;
573 }
574
575 if (conf->library) {
576
577 const apu_err_t *err = NULL;
578 apr_status_t rv;
579
580 rv = apr_crypto_init(p);
581 if (APR_SUCCESS != rv) {
583 "APR crypto could not be initialised");
584 return rv;
585 }
586
587 rv = apr_crypto_get_driver(&driver, conf->library, conf->params, &err, p);
588 if (APR_EREINIT == rv) {
590 "warning: crypto for '%s' was already initialised, "
591 "using existing configuration", conf->library);
592 rv = APR_SUCCESS;
593 }
594 if (APR_SUCCESS != rv && err) {
596 "The crypto library '%s' could not be loaded: %s (%s: %d)", conf->library, err->msg, err->reason, err->rc);
597 return rv;
598 }
599 if (APR_ENOTIMPL == rv) {
601 "The crypto library '%s' could not be found",
602 conf->library);
603 return rv;
604 }
605 if (APR_SUCCESS != rv || !driver) {
607 "The crypto library '%s' could not be loaded",
608 conf->library);
609 return rv;
610 }
611
612 rv = apr_crypto_make(&f, driver, conf->params, p);
613 if (APR_SUCCESS != rv) {
615 "The crypto library '%s' could not be initialised",
616 conf->library);
617 return rv;
618 }
619
621 "The crypto library '%s' was loaded successfully",
622 conf->library);
623
624 apr_pool_userdata_set((const void *)f, CRYPTO_KEY,
625 apr_pool_cleanup_null, s->process->pconf);
626
627 }
628
629 return OK;
630}
631
633{
636
637 /* if no library has been configured, set the recommended library
638 * as a sensible default.
639 */
640#ifdef APU_CRYPTO_RECOMMENDED_DRIVER
641 new->library = APU_CRYPTO_RECOMMENDED_DRIVER;
642#endif
643
644 return (void *) new;
645}
646
648{
651
652 new->passphrases = apr_array_make(p, 10, sizeof(char *));
653
654 /* default cipher AES256-SHA */
655 new->cipher = "aes256";
656
657 return (void *) new;
658}
659
660static void *merge_session_crypto_dir_config(apr_pool_t * p, void *basev, void *addv)
661{
665
666 new->passphrases = (add->passphrases_set == 0) ? base->passphrases : add->passphrases;
667 new->passphrases_set = add->passphrases_set || base->passphrases_set;
668 new->cipher = (add->cipher_set == 0) ? base->cipher : add->cipher;
669 new->cipher_set = add->cipher_set || base->cipher_set;
670
671 return new;
672}
673
674static const char *set_crypto_driver(cmd_parms * cmd, void *config, const char *arg)
675{
676 session_crypto_conf *conf =
677 (session_crypto_conf *)ap_get_module_config(cmd->server->module_config,
679
680 const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
681
682 if (err != NULL) {
683 return err;
684 }
685
686 conf->library = ap_getword_conf(cmd->pool, &arg);
687 conf->params = arg;
688 conf->library_set = 1;
689
690 return NULL;
691}
692
693static const char *set_crypto_passphrase(cmd_parms * cmd, void *config, const char *arg)
694{
695 int arglen = strlen(arg);
696 char **argv;
697 char *result;
698 const char **passphrase;
700
701 passphrase = apr_array_push(dconf->passphrases);
702
703 if ((arglen > 5) && strncmp(arg, "exec:", 5) == 0) {
704 if (apr_tokenize_to_argv(arg+5, &argv, cmd->temp_pool) != APR_SUCCESS) {
705 return apr_pstrcat(cmd->pool,
706 "Unable to parse exec arguments from ",
707 arg+5, NULL);
708 }
709 argv[0] = ap_server_root_relative(cmd->temp_pool, argv[0]);
710
711 if (!argv[0]) {
712 return apr_pstrcat(cmd->pool,
713 "Invalid SessionCryptoPassphrase exec location:",
714 arg+5, NULL);
715 }
717 (const char*)argv[0], (const char * const *)argv);
718
719 if(!result) {
720 return apr_pstrcat(cmd->pool,
721 "Unable to get bind password from exec of ",
722 arg+5, NULL);
723 }
725 }
726 else {
727 *passphrase = arg;
728 }
729
730 dconf->passphrases_set = 1;
731
732 return NULL;
733}
734
735static const char *set_crypto_passphrase_file(cmd_parms *cmd, void *config,
736 const char *filename)
737{
739 char *arg;
740 const char *args;
742 apr_status_t rv;
743
745 rv = ap_pcfg_openfile(&file, cmd->temp_pool, filename);
746 if (rv != APR_SUCCESS) {
747 return apr_psprintf(cmd->pool, "%s: Could not open file %s: %pm",
748 cmd->cmd->name, filename, &rv);
749 }
750
751 while (!(ap_cfg_getline(buffer, sizeof(buffer), file))) {
752 args = buffer;
753 while (*(arg = ap_getword_conf(cmd->pool, &args)) != '\0') {
754 if (*arg == '#') {
755 break;
756 }
757 set_crypto_passphrase(cmd, config, arg);
758 }
759 }
760
762
763 return NULL;
764}
765
766static const char *set_crypto_cipher(cmd_parms * cmd, void *config, const char *cipher)
767{
769
770 dconf->cipher = cipher;
771 dconf->cipher_set = 1;
772
773 return NULL;
774}
775
776static const command_rec session_crypto_cmds[] =
777{
779 "The passphrase(s) used to encrypt the session. First will be used for encryption, all phrases will be accepted for decryption"),
780 AP_INIT_TAKE1("SessionCryptoPassphraseFile", set_crypto_passphrase_file, NULL, RSRC_CONF|ACCESS_CONF,
781 "File containing passphrase(s) used to encrypt the session, one per line. First will be used for encryption, all phrases will be accepted for decryption"),
783 "The underlying crypto cipher to use"),
784 AP_INIT_RAW_ARGS("SessionCryptoDriver", set_crypto_driver, NULL, RSRC_CONF,
785 "The underlying crypto library driver to use"),
786 { NULL }
787};
788
789static void register_hooks(apr_pool_t * p)
790{
794}
795
797{
799 create_session_crypto_dir_config, /* dir config creater */
800 merge_session_crypto_dir_config, /* dir merger --- default is to override */
801 create_session_crypto_config, /* server config */
802 NULL, /* merge server config */
803 session_crypto_cmds, /* command apr_table_t */
804 register_hooks /* register hooks */
805};
806
807#endif
const char apr_size_t len
Definition ap_regex.h:187
APR-UTIL Base64 Encoding.
APR-UTIL Crypto library.
static const char base64[]
Definition apr_encode.c:198
APR general purpose library routines.
APR MD5 Routines.
#define U8TO64_LE(p)
Definition apr_siphash.c:26
#define U64TO8_LE(p, v)
Definition apr_siphash.c:36
#define SIPROUND()
Definition apr_siphash.c:48
APR-UTIL siphash library "SipHash-c-d is a family of pseudorandom functions (a.k.a....
APR Strings library.
APR-util Versioning Interface.
#define AP_INIT_TAKE1(directive, func, mconfig, where, help)
#define ap_get_module_config(v, m)
int ap_cfg_closefile(ap_configfile_t *cfp)
Definition util.c:931
void ap_hook_post_config(ap_HOOK_post_config_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition config.c:105
apr_status_t ap_pcfg_openfile(ap_configfile_t **ret_cfg, apr_pool_t *p, const char *name)
Definition util.c:957
#define AP_DECLARE_MODULE(foo)
ap_conf_vector_t * base
#define AP_INIT_ITERATE(directive, func, mconfig, where, help)
char * ap_server_root_relative(apr_pool_t *p, const char *fname)
Definition config.c:1594
#define AP_INIT_RAW_ARGS(directive, func, mconfig, where, help)
request_rec * r
apr_status_t ap_cfg_getline(char *buf, apr_size_t bufsize, ap_configfile_t *cfp)
Definition util.c:1198
#define MAX_STRING_LEN
Definition httpd.h:300
#define OK
Definition httpd.h:456
#define AP_SQ_MS_CREATE_PRE_CONFIG
Definition http_core.h:1047
int ap_state_query(int query_code)
Definition core.c:5378
#define AP_SQ_MAIN_STATE
Definition http_core.h:1030
#define APLOGNO(n)
Definition http_log.h:117
#define APLOG_INFO
Definition http_log.h:70
#define ap_log_rerror
Definition http_log.h:454
#define APLOG_ERR
Definition http_log.h:67
#define ap_log_error
Definition http_log.h:370
#define APLOG_MARK
Definition http_log.h:283
#define APLOG_WARNING
Definition http_log.h:68
#define APLOG_DEBUG
Definition http_log.h:71
void * dummy
Definition http_vhost.h:62
void const char * arg
Definition http_vhost.h:63
#define APR_EGENERAL
Definition apr_errno.h:313
#define APR_ENOTIMPL
Definition apr_errno.h:476
const char * salt
Definition apr_md5.h:139
#define APR_MD5_DIGESTSIZE
Definition apr_md5.h:68
apr_file_t * f
const char const apr_dbd_driver_t ** driver
Definition apr_dbd.h:106
apr_pool_t apr_dbd_t apr_dbd_results_t ** res
Definition apr_dbd.h:287
apr_pool_t const char * params
Definition apr_dbd.h:141
const char * src
Definition apr_encode.h:167
#define APR_STATUS_IS_ENOKEY(s)
Definition apu_errno.h:109
#define APR_STATUS_IS_EKEYTYPE(s)
Definition apu_errno.h:117
#define APR_EREINIT
Definition apu_errno.h:85
#define APR_ECRYPT
Definition apu_errno.h:71
#define APR_STATUS_IS_EPADDING(s)
Definition apu_errno.h:129
#define APR_HOOK_FIRST
Definition apr_hooks.h:301
#define APR_HOOK_LAST
Definition apr_hooks.h:305
#define ACCESS_CONF
#define RSRC_CONF
#define OR_AUTHCFG
void ap_hook_session_encode(ap_HOOK_session_encode_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition mod_session.c:39
void ap_hook_session_decode(ap_HOOK_session_decode_t *pf, const char *const *aszPre, const char *const *aszSucc, int nOrder)
Definition mod_session.c:41
#define STANDARD20_MODULE_STUFF
char * ap_get_exec_line(apr_pool_t *p, const char *cmd, const char *const *argv)
Definition util.c:3386
char * ap_getword_conf(apr_pool_t *p, const char **line)
Definition util.c:833
#define GLOBAL_ONLY
const char * ap_check_cmd_context(cmd_parms *cmd, unsigned forbidden)
Definition core.c:1301
apr_size_t size
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
const char * key
apr_seek_where_t apr_off_t * offset
const char apr_file_t * file
char * buffer
apr_array_header_t ** result
const apr_hash_t * h
Definition apr_hash.h:97
apr_ssize_t * klen
Definition apr_hash.h:71
#define APR_HASH_KEY_STRING
Definition apr_hash.h:47
#define apr_pcalloc(p, size)
Definition apr_pools.h:465
apr_size_t const char * filename
Definition apr_shm.h:72
const char char ** end
const char * s
Definition apr_strings.h:95
const void * m
#define APR_ARRAY_IDX(ary, i, type)
Definition apr_tables.h:141
apr_int32_t apr_int32_t apr_int32_t err
apr_int32_t in
apr_cmdtype_e cmd
const char const char *const * args
CORE HTTP Daemon.
Apache Logging library.
apr_pool_t * p
Definition md_event.c:32
static void register_hooks(apr_pool_t *p)
static apr_file_t * out
Definition mod_info.c:85
const char * argv[3]
Session Module for Apache.
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
apr_pool_t * pconf
Definition httpd.h:833
A structure that represents the current request.
Definition httpd.h:845
apr_pool_t * pool
Definition httpd.h:847
server_rec * server
Definition httpd.h:851
struct ap_conf_vector_t * per_dir_config
Definition httpd.h:1047
A structure to store information for each virtual server.
Definition httpd.h:1322
process_rec * process
Definition httpd.h:1324
typedef int(WSAAPI *apr_winapi_fpt_WSAPoll)(IN OUT LPWSAPOLLFD fdArray