2 * Copyright (C) 2005-2011 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, "REQ[%X] start %s() cookie_id:[%s]", TO_ADDR(r), __func__,cookie_id);
45 file = chxj_cookie_db_lock(r);
47 ERR(r, "REQ[%X] %s:%d mod_chxj: Can't lock cookie db", TO_ADDR(r), __FILE__,__LINE__);
48 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r), __func__,cookie_id);
52 retval = apr_dbm_open_ex(&f,
53 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
54 chxj_cookie_db_name_create(r, m->cookie_db_dir),
58 if (retval != APR_SUCCESS) {
60 ERR(r, "REQ[%X] %s:%d could not open dbm (type %s) auth file: %s(%d:%s)",
64 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
65 chxj_cookie_db_name_create(r,m->cookie_db_dir),
67 apr_strerror(retval, errstr, 255));
68 chxj_cookie_db_unlock(r, file);
69 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r), __func__,cookie_id);
78 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
79 dbmkey.dsize = strlen(cookie_id);
80 dbmval.dptr = apr_pstrdup(r->pool, store_string);
81 dbmval.dsize = strlen(store_string);
86 retval = apr_dbm_store(f, dbmkey, dbmval);
87 if (retval != APR_SUCCESS) {
89 ERR(r, "REQ[%X] %s:%d Cannot store Cookie data to DBM file `%s' tye:[%s] (%d:%s) key:[%s] val:[%s]",
93 chxj_cookie_db_name_create(r, m->cookie_db_dir),
94 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
96 apr_strerror(retval, errstr, 255),
100 chxj_cookie_db_unlock(r, file);
101 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r), __func__,cookie_id);
106 chxj_cookie_db_unlock(r, file);
107 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r), __func__,cookie_id);
113 chxj_cookie_db_unlock(request_rec *r, apr_file_t *file)
117 rv = apr_file_unlock(file);
118 if (rv != APR_SUCCESS) {
119 ERR(r, "cookie lock file open failed.");
123 apr_file_close(file);
128 chxj_cookie_db_lock(request_rec *r)
132 mod_chxj_config *dconf;
134 dconf = (mod_chxj_config*)chxj_get_module_config(r->per_dir_config, &chxj_module);
136 rv = apr_file_open(&file,
137 chxj_cookie_db_lock_name_create(r, dconf->cookie_db_dir),
138 APR_CREATE|APR_WRITE,
141 if (rv != APR_SUCCESS) {
142 ERR(r, "cookie lock file open failed.");
146 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
147 if (rv != APR_SUCCESS) {
148 ERR(r, "cookie lock file open failed.");
149 apr_file_close(file);
158 chxj_cookie_db_name_create(request_rec *r, const char *dir)
163 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
166 dst = apr_pstrdup(r->pool, dir);
169 if (dst[strlen(dst)-1] != '/') {
170 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_NAME, NULL);
173 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_NAME, NULL);
181 chxj_cookie_db_lock_name_create(request_rec *r, const char *dir)
184 DBG(r, "REQ[%X] start %s()", TO_ADDR(r),__func__);
187 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
190 dst = apr_pstrdup(r->pool, dir);
192 if (dst[strlen(dst)-1] != '/') {
193 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_LOCK_NAME, NULL);
196 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_LOCK_NAME, NULL);
198 DBG(r, "REQ[%X] end %s()", TO_ADDR(r),__func__);
205 chxj_cookie_expire_db_name_create(request_rec *r, const char *dir)
210 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
213 dst = apr_pstrdup(r->pool, dir);
216 if (dst[strlen(dst)-1] != '/') {
217 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_NAME, NULL);
220 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_NAME, NULL);
228 chxj_cookie_expire_db_lock_name_create(request_rec *r, const char *dir)
233 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
236 dst = apr_pstrdup(r->pool, dir);
238 if (dst[strlen(dst)-1] != '/') {
239 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
242 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
250 chxj_cookie_expire_db_lock(request_rec *r)
254 mod_chxj_config *dconf;
256 dconf = (mod_chxj_config *)chxj_get_module_config(r->per_dir_config, &chxj_module);
258 rv = apr_file_open(&file,
259 chxj_cookie_expire_db_lock_name_create(r, dconf->cookie_db_dir),
260 APR_CREATE|APR_WRITE,
263 if (rv != APR_SUCCESS) {
264 ERR(r, "cookie lock file open failed.");
268 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
269 if (rv != APR_SUCCESS) {
270 ERR(r, "cookie lock file open failed.");
271 apr_file_close(file);
280 chxj_cookie_expire_db_unlock(request_rec *r, apr_file_t *file)
284 rv = apr_file_unlock(file);
285 if (rv != APR_SUCCESS) {
286 ERR(r, "cookie lock file open failed.");
290 apr_file_close(file);
294 chxj_update_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
302 DBG(r, "REQ[%X] start %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
304 file = chxj_cookie_db_lock(r);
306 ERR(r, "REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
307 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
311 retval = apr_dbm_open_ex(&f,
312 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
313 chxj_cookie_db_name_create(r, m->cookie_db_dir),
317 if (retval != APR_SUCCESS) {
318 ERR(r, "REQ[%X] could not open dbm (type %s) auth file: %s",
320 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
321 chxj_cookie_db_name_create(r,m->cookie_db_dir));
322 chxj_cookie_db_unlock(r, file);
323 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
332 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
333 dbmkey.dsize = strlen(cookie_id);
338 dbmval.dptr = apr_pstrdup(r->pool, store_string);
339 dbmval.dsize = strlen(store_string);
344 retval = apr_dbm_store(f, dbmkey, dbmval);
345 if (retval != APR_SUCCESS) {
347 ERR(r, "REQ[%X] %s:%d Cannot store Cookie data to DBM file `%s' tye:[%s] (%d:%s) key:[%s] val:[%s]",
351 chxj_cookie_db_name_create(r, m->cookie_db_dir),
352 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
354 apr_strerror(retval, errstr, 255),
358 chxj_cookie_db_unlock(r, file);
359 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
363 chxj_cookie_db_unlock(r, file);
364 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
370 chxj_load_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
372 char *load_string = NULL;
379 DBG(r, "REQ[%X] start %s() cookie_id:[%s]", TO_ADDR(r), __func__,cookie_id);
380 file = chxj_cookie_db_lock(r);
382 ERR(r, "REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
383 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r), __func__,cookie_id);
387 retval = apr_dbm_open_ex(&f,
388 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
389 chxj_cookie_db_name_create(r, m->cookie_db_dir),
393 if (retval != APR_SUCCESS) {
396 "REQ[%X] %s:%d could not open dbm (type %s) auth file: %s (%d:%s)",
400 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
401 chxj_cookie_db_name_create(r, m->cookie_db_dir),
403 apr_strerror(retval, errstr, 255));
404 chxj_cookie_db_unlock(r, file);
405 DBG(r, "TO_REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r), __func__,cookie_id);
412 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
413 dbmkey.dsize = strlen(dbmkey.dptr);
415 if (apr_dbm_exists(f, dbmkey)) {
416 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
417 if (retval != APR_SUCCESS) {
420 "REQ[%X] %s:%d could not fetch dbm (type %s) auth file: %s(%d:%s)",
424 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
425 chxj_cookie_db_name_create(r, m->cookie_db_dir),
427 apr_strerror(retval, errstr, 255));
429 chxj_cookie_db_unlock(r, file);
430 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r), __func__,cookie_id);
433 load_string = apr_palloc(r->pool, dbmval.dsize+1);
435 memset(load_string, 0, dbmval.dsize+1);
436 memcpy(load_string, dbmval.dptr, dbmval.dsize);
439 DBG(r, "REQ[%X] Not Found cookie_id:[%s]", TO_ADDR(r), cookie_id);
440 load_string = apr_pstrdup(r->pool, "");
443 chxj_cookie_db_unlock(r, file);
444 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r), __func__, cookie_id);
450 chxj_delete_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
457 DBG(r, "REQ[%X] start %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
458 file = chxj_cookie_db_lock(r);
460 ERR(r, "REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
461 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
465 retval = apr_dbm_open_ex(&f,
466 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
467 chxj_cookie_db_name_create(r, m->cookie_db_dir),
471 if (retval != APR_SUCCESS) {
473 "REQ[%X] could not open dbm (type %s) auth file: %s",
475 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
476 chxj_cookie_db_name_create(r,m->cookie_db_dir));
477 chxj_cookie_db_unlock(r, file);
478 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
485 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
486 dbmkey.dsize = strlen(dbmkey.dptr);
487 if (apr_dbm_exists(f, dbmkey)) {
488 apr_dbm_delete(f, dbmkey);
491 chxj_cookie_db_unlock(r, file);
492 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
498 chxj_save_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
507 DBG(r, "REQ[%X] start %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
508 file = chxj_cookie_expire_db_lock(r);
510 ERR(r, "REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
511 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
515 retval = apr_dbm_open_ex(&f,
516 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
517 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
521 if (retval != APR_SUCCESS) {
522 ERR(r, "REQ[%X] could not open dbm (type %s) auth file: %s",
524 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
525 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
526 chxj_cookie_expire_db_unlock(r, file);
527 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
534 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
535 dbmkey.dsize = strlen(cookie_id);
541 store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
542 dbmval.dptr = store_string;
543 dbmval.dsize = strlen(store_string);
548 retval = apr_dbm_store(f, dbmkey, dbmval);
549 if (retval != APR_SUCCESS) {
550 ERR(r, "REQ[%X] Cannot store Cookie data to DBM file `%s'",
552 chxj_cookie_db_name_create(r, m->cookie_db_dir));
553 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
555 chxj_cookie_expire_db_unlock(r, file);
561 chxj_cookie_expire_db_unlock(r, file);
562 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
569 chxj_delete_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
576 DBG(r, "REQ[%X] start %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
577 file = chxj_cookie_expire_db_lock(r);
579 ERR(r, "REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
580 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
583 retval = apr_dbm_open_ex(&f,
584 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
585 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
589 if (retval != APR_SUCCESS) {
591 "REQ[%X] could not open dbm (type %s) auth file: %s",
593 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
594 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
595 chxj_cookie_expire_db_unlock(r, file);
596 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
603 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
604 dbmkey.dsize = strlen(dbmkey.dptr);
605 if (apr_dbm_exists(f, dbmkey)) {
606 apr_dbm_delete(f, dbmkey);
609 chxj_cookie_expire_db_unlock(r, file);
610 DBG(r, "REQ[%X] end %s() cookie_id:[%s]", TO_ADDR(r),__func__,cookie_id);
617 chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m)
626 DBG(r, "REQ[%X] start %s()",TO_ADDR(r),__func__);
628 file = chxj_cookie_expire_db_lock(r);
630 ERR(r, "REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
631 DBG(r, "REQ[%X] end %s()",TO_ADDR(r),__func__);
635 retval = apr_dbm_open_ex(&f,
636 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
637 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
641 if (retval != APR_SUCCESS) {
643 "REQ[%X] could not open dbm (type %s) auth file: %s",
645 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
646 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
647 chxj_cookie_expire_db_unlock(r, file);
648 DBG(r, "REQ[%X] end %s()", TO_ADDR(r),__func__);
655 memset(&dbmkey, 0, sizeof(apr_datum_t));
657 now_time = time(NULL);
659 retval = apr_dbm_firstkey(f, &dbmkey);
660 if (retval == APR_SUCCESS) {
661 DBG(r, "REQ[%X] firstkey=[%.*s]", TO_ADDR(r),(int)dbmkey.dsize, dbmkey.dptr);
668 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
669 if (retval != APR_SUCCESS) {
672 tmp = apr_palloc(r->pool, dbmval.dsize+1);
673 memset(tmp, 0, dbmval.dsize+1);
674 memcpy(tmp, dbmval.dptr, dbmval.dsize);
677 val_time = atoi(tmp);
679 if (m->cookie_timeout == 0)
680 cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
682 cmp_time = now_time - m->cookie_timeout;
684 DBG(r, "REQ[%X] m->cookie_timeout=[%d]", TO_ADDR(r),(int)m->cookie_timeout);
685 DBG(r, "REQ[%X] key=[%.*s] cmp_time=[%d] val_time=[%d]", TO_ADDR(r),(int)dbmkey.dsize, dbmkey.dptr, cmp_time, val_time);
686 if (cmp_time >= val_time) {
687 apr_dbm_delete(f, dbmkey);
689 old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
690 memset(old_cookie_id, 0, dbmkey.dsize+1);
691 memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
693 chxj_delete_cookie(r,old_cookie_id);
694 DBG(r, "REQ[%X] detect timeout cookie [%s]", TO_ADDR(r),old_cookie_id);
697 retval = apr_dbm_nextkey(f, &dbmkey);
698 } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
702 chxj_cookie_expire_db_unlock(r, file);
703 DBG(r, "REQ[%X] end %s()",TO_ADDR(r),__func__);
709 chxj_cookie_lock_dbm(request_rec *r, mod_chxj_config *UNUSED(m))
711 cookie_lock_t *ret = apr_palloc(r->pool, sizeof(*ret));
712 ret->file = chxj_cookie_db_lock(r);
718 chxj_cookie_unlock_dbm(request_rec *r, cookie_lock_t *lock, mod_chxj_config *UNUSED(m))
720 chxj_cookie_expire_db_unlock(r, lock->file);
721 return 1; /* allways true */