2 * Copyright (C) 2005-2009 Atsushi Konno All rights reserved.
3 * Copyright (C) 2005 QSDN,Inc. All rights reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #include "chxj_cookie.h"
20 #include "chxj_url_encode.h"
21 #include "chxj_apply_convrule.h"
22 #include "chxj_str_util.h"
24 #include "ap_release.h"
29 #include "apr_base64.h"
35 chxj_save_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
43 DBG(r, "start chxj_save_cookie_dbm() cookie_id:[%s]", cookie_id);
45 file = chxj_cookie_db_lock(r);
47 ERR(r, "mod_chxj: Can't lock cookie db");
48 DBG(r, "end chxj_save_cookie_dbm() cookie_id:[%s]", cookie_id);
52 retval = apr_dbm_open_ex(&f,
54 chxj_cookie_db_name_create(r, m->cookie_db_dir),
58 if (retval != APR_SUCCESS) {
60 ERR(r, "%s:%d could not open dbm (type %s) auth file: %s(%d:%s)",
64 chxj_cookie_db_name_create(r,m->cookie_db_dir),
66 apr_strerror(retval, errstr, 255));
67 chxj_cookie_db_unlock(r, file);
68 DBG(r, "end chxj_save_cookie_dbm() cookie_id:[%s]", cookie_id);
77 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
78 dbmkey.dsize = strlen(cookie_id);
79 dbmval.dptr = apr_pstrdup(r->pool, store_string);
80 dbmval.dsize = strlen(store_string);
85 retval = apr_dbm_store(f, dbmkey, dbmval);
86 if (retval != APR_SUCCESS) {
88 ERR(r, "%s:%d Cannot store Cookie data to DBM file `%s' (%d:%s)",
91 chxj_cookie_db_name_create(r, m->cookie_db_dir),
93 apr_strerror(retval, errstr, 255));
95 chxj_cookie_db_unlock(r, file);
96 DBG(r, "end chxj_save_cookie_dbm() cookie_id:[%s]", cookie_id);
101 chxj_cookie_db_unlock(r, file);
102 DBG(r, "end chxj_save_cookie_dbm() cookie_id:[%s]", cookie_id);
108 chxj_cookie_db_unlock(request_rec *r, apr_file_t *file)
112 rv = apr_file_unlock(file);
113 if (rv != APR_SUCCESS) {
114 ERR(r, "cookie lock file open failed.");
118 apr_file_close(file);
123 chxj_cookie_db_lock(request_rec *r)
127 mod_chxj_config *dconf;
129 dconf = (mod_chxj_config*)chxj_get_module_config(r->per_dir_config, &chxj_module);
131 rv = apr_file_open(&file,
132 chxj_cookie_db_lock_name_create(r, dconf->cookie_db_dir),
133 APR_CREATE|APR_WRITE,
136 if (rv != APR_SUCCESS) {
137 ERR(r, "cookie lock file open failed.");
141 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
142 if (rv != APR_SUCCESS) {
143 ERR(r, "cookie lock file open failed.");
144 apr_file_close(file);
153 chxj_cookie_db_name_create(request_rec *r, const char *dir)
158 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
161 dst = apr_pstrdup(r->pool, dir);
164 if (dst[strlen(dst)-1] != '/') {
165 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_NAME, NULL);
168 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_NAME, NULL);
176 chxj_cookie_db_lock_name_create(request_rec *r, const char *dir)
179 DBG(r, "start chxj_cookie_db_lock_name_create()");
183 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
187 dst = apr_pstrdup(r->pool, dir);
190 DBG(r, "dst[strlen(dst)-1]=[%c]", dst[strlen(dst)-1]);
191 if (dst[strlen(dst)-1] != '/') {
192 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_LOCK_NAME, NULL);
195 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_LOCK_NAME, NULL);
197 DBG(r, "end chxj_cookie_db_lock_name_create()");
204 chxj_cookie_expire_db_name_create(request_rec *r, const char *dir)
209 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
212 dst = apr_pstrdup(r->pool, dir);
215 if (dst[strlen(dst)-1] != '/') {
216 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_NAME, NULL);
219 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_NAME, NULL);
227 chxj_cookie_expire_db_lock_name_create(request_rec *r, const char *dir)
232 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
235 dst = apr_pstrdup(r->pool, dir);
237 if (dst[strlen(dst)-1] != '/') {
238 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
241 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
249 chxj_cookie_expire_db_lock(request_rec *r)
253 mod_chxj_config *dconf;
255 dconf = (mod_chxj_config *)chxj_get_module_config(r->per_dir_config, &chxj_module);
257 rv = apr_file_open(&file,
258 chxj_cookie_expire_db_lock_name_create(r, dconf->cookie_db_dir),
259 APR_CREATE|APR_WRITE,
262 if (rv != APR_SUCCESS) {
263 ERR(r, "cookie lock file open failed.");
267 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
268 if (rv != APR_SUCCESS) {
269 ERR(r, "cookie lock file open failed.");
270 apr_file_close(file);
279 chxj_cookie_expire_db_unlock(request_rec *r, apr_file_t *file)
283 rv = apr_file_unlock(file);
284 if (rv != APR_SUCCESS) {
285 ERR(r, "cookie lock file open failed.");
289 apr_file_close(file);
293 chxj_update_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
301 DBG(r, "start chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
303 file = chxj_cookie_db_lock(r);
305 ERR(r, "mod_chxj: Can't lock cookie db");
306 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
310 retval = apr_dbm_open_ex(&f,
312 chxj_cookie_db_name_create(r, m->cookie_db_dir),
316 if (retval != APR_SUCCESS) {
317 ERR(r, "could not open dbm (type %s) auth file: %s",
319 chxj_cookie_db_name_create(r,m->cookie_db_dir));
320 chxj_cookie_db_unlock(r, file);
321 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
330 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
331 dbmkey.dsize = strlen(cookie_id);
336 dbmval.dptr = apr_pstrdup(r->pool, store_string);
337 dbmval.dsize = strlen(store_string);
342 retval = apr_dbm_store(f, dbmkey, dbmval);
343 if (retval != APR_SUCCESS) {
344 ERR(r, "Cannot store Cookie data to DBM file `%s'",
345 chxj_cookie_db_name_create(r, m->cookie_db_dir));
347 chxj_cookie_db_unlock(r, file);
348 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
352 chxj_cookie_db_unlock(r, file);
353 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
359 chxj_load_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
361 char *load_string = NULL;
368 DBG(r, "start chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
369 file = chxj_cookie_db_lock(r);
371 ERR(r, "mod_chxj: Can't lock cookie db");
372 DBG(r, "end chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
376 retval = apr_dbm_open_ex(&f,
378 chxj_cookie_db_name_create(r, m->cookie_db_dir),
382 if (retval != APR_SUCCESS) {
384 "could not open dbm (type %s) auth file: %s",
386 chxj_cookie_db_name_create(r, m->cookie_db_dir));
387 chxj_cookie_db_unlock(r, file);
388 DBG(r, "end chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
395 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
396 dbmkey.dsize = strlen(dbmkey.dptr);
398 if (apr_dbm_exists(f, dbmkey)) {
399 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
400 if (retval != APR_SUCCESS) {
402 "could not fetch dbm (type %s) auth file: %s", "default",
403 chxj_cookie_db_name_create(r, m->cookie_db_dir));
405 chxj_cookie_db_unlock(r, file);
406 DBG(r, "end chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
409 load_string = apr_palloc(r->pool, dbmval.dsize+1);
411 memset(load_string, 0, dbmval.dsize+1);
412 memcpy(load_string, dbmval.dptr, dbmval.dsize);
415 chxj_cookie_db_unlock(r, file);
416 DBG(r, "end chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
422 chxj_delete_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
429 DBG(r, "start chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
430 file = chxj_cookie_db_lock(r);
432 ERR(r, "mod_chxj: Can't lock cookie db");
433 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
437 retval = apr_dbm_open_ex(&f,
439 chxj_cookie_db_name_create(r, m->cookie_db_dir),
443 if (retval != APR_SUCCESS) {
445 "could not open dbm (type %s) auth file: %s",
447 chxj_cookie_db_name_create(r,m->cookie_db_dir));
448 chxj_cookie_db_unlock(r, file);
449 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
456 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
457 dbmkey.dsize = strlen(dbmkey.dptr);
458 if (apr_dbm_exists(f, dbmkey)) {
459 apr_dbm_delete(f, dbmkey);
462 chxj_cookie_db_unlock(r, file);
463 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
469 chxj_save_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
478 DBG(r, "start chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
479 file = chxj_cookie_expire_db_lock(r);
481 ERR(r, "mod_chxj: Can't lock cookie db");
482 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
486 retval = apr_dbm_open_ex(&f,
488 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
492 if (retval != APR_SUCCESS) {
493 ERR(r, "could not open dbm (type %s) auth file: %s",
495 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
496 chxj_cookie_expire_db_unlock(r, file);
497 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
504 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
505 dbmkey.dsize = strlen(cookie_id);
511 store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
512 dbmval.dptr = store_string;
513 dbmval.dsize = strlen(store_string);
518 retval = apr_dbm_store(f, dbmkey, dbmval);
519 if (retval != APR_SUCCESS) {
520 ERR(r, "Cannot store Cookie data to DBM file `%s'",
521 chxj_cookie_db_name_create(r, m->cookie_db_dir));
522 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
524 chxj_cookie_expire_db_unlock(r, file);
530 chxj_cookie_expire_db_unlock(r, file);
531 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
538 chxj_delete_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
545 DBG(r, "start chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
546 file = chxj_cookie_expire_db_lock(r);
548 ERR(r, "mod_chxj: Can't lock cookie db");
549 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
552 retval = apr_dbm_open_ex(&f,
554 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
558 if (retval != APR_SUCCESS) {
560 "could not open dbm (type %s) auth file: %s",
562 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
563 chxj_cookie_expire_db_unlock(r, file);
564 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
571 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
572 dbmkey.dsize = strlen(dbmkey.dptr);
573 if (apr_dbm_exists(f, dbmkey)) {
574 apr_dbm_delete(f, dbmkey);
577 chxj_cookie_expire_db_unlock(r, file);
578 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
585 chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m)
594 DBG(r, "start chxj_cookie_expire_gc_dbm()");
596 file = chxj_cookie_expire_db_lock(r);
598 ERR(r, "mod_chxj: Can't lock cookie db");
599 DBG(r, "end chxj_cookie_expire_gc_dbm()");
603 retval = apr_dbm_open_ex(&f,
605 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
609 if (retval != APR_SUCCESS) {
611 "could not open dbm (type %s) auth file: %s",
613 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
614 chxj_cookie_expire_db_unlock(r, file);
615 DBG(r, "end chxj_cookie_expire_gc_dbm()");
622 memset(&dbmkey, 0, sizeof(apr_datum_t));
624 now_time = time(NULL);
626 retval = apr_dbm_firstkey(f, &dbmkey);
627 if (retval == APR_SUCCESS) {
628 DBG(r, "firstkey=[%.*s]", (int)dbmkey.dsize, dbmkey.dptr);
635 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
636 if (retval != APR_SUCCESS) {
639 tmp = apr_palloc(r->pool, dbmval.dsize+1);
640 memset(tmp, 0, dbmval.dsize+1);
641 memcpy(tmp, dbmval.dptr, dbmval.dsize);
644 val_time = atoi(tmp);
646 if (m->cookie_timeout == 0)
647 cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
649 cmp_time = now_time - m->cookie_timeout;
651 DBG(r, "m->cookie_timeout=[%d]", (int)m->cookie_timeout);
652 DBG(r, "key=[%.*s] cmp_time=[%d] val_time=[%d]", (int)dbmkey.dsize, dbmkey.dptr, cmp_time, val_time);
653 if (cmp_time >= val_time) {
654 apr_dbm_delete(f, dbmkey);
656 old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
657 memset(old_cookie_id, 0, dbmkey.dsize+1);
658 memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
660 chxj_delete_cookie(r,old_cookie_id);
661 DBG(r, "detect timeout cookie [%s]", old_cookie_id);
664 retval = apr_dbm_nextkey(f, &dbmkey);
665 } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
669 chxj_cookie_expire_db_unlock(r, file);
670 DBG(r, "end chxj_cookie_expire_gc_dbm()");
676 chxj_cookie_lock_dbm(request_rec *r, mod_chxj_config *UNUSED(m))
678 cookie_lock_t *ret = apr_palloc(r->pool, sizeof(*ret));
679 ret->file = chxj_cookie_db_lock(r);
685 chxj_cookie_unlock_dbm(request_rec *r, cookie_lock_t *lock, mod_chxj_config *UNUSED(m))
687 chxj_cookie_expire_db_unlock(r, lock->file);
688 return 1; /* allways true */