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, "REQ[%X] start chxj_save_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
45 file = chxj_cookie_db_lock(r);
47 ERR(r, "%s:%d REQ[%X] mod_chxj: Can't lock cookie db", __FILE__,__LINE__,TO_ADDR(r));
48 DBG(r, "REQ[%X] end chxj_save_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), 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, "REQ[%X] end chxj_save_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), 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, "REQ[%X] end chxj_save_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
101 chxj_cookie_db_unlock(r, file);
102 DBG(r, "REQ[%X] end chxj_save_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), 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, "REQ[%X] start chxj_cookie_db_lock_name_create()", TO_ADDR(r));
182 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
185 dst = apr_pstrdup(r->pool, dir);
187 if (dst[strlen(dst)-1] != '/') {
188 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_LOCK_NAME, NULL);
191 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_LOCK_NAME, NULL);
193 DBG(r, "REQ[%X] end chxj_cookie_db_lock_name_create()", TO_ADDR(r));
200 chxj_cookie_expire_db_name_create(request_rec *r, const char *dir)
205 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
208 dst = apr_pstrdup(r->pool, dir);
211 if (dst[strlen(dst)-1] != '/') {
212 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_NAME, NULL);
215 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_NAME, NULL);
223 chxj_cookie_expire_db_lock_name_create(request_rec *r, const char *dir)
228 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
231 dst = apr_pstrdup(r->pool, dir);
233 if (dst[strlen(dst)-1] != '/') {
234 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
237 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
245 chxj_cookie_expire_db_lock(request_rec *r)
249 mod_chxj_config *dconf;
251 dconf = (mod_chxj_config *)chxj_get_module_config(r->per_dir_config, &chxj_module);
253 rv = apr_file_open(&file,
254 chxj_cookie_expire_db_lock_name_create(r, dconf->cookie_db_dir),
255 APR_CREATE|APR_WRITE,
258 if (rv != APR_SUCCESS) {
259 ERR(r, "cookie lock file open failed.");
263 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
264 if (rv != APR_SUCCESS) {
265 ERR(r, "cookie lock file open failed.");
266 apr_file_close(file);
275 chxj_cookie_expire_db_unlock(request_rec *r, apr_file_t *file)
279 rv = apr_file_unlock(file);
280 if (rv != APR_SUCCESS) {
281 ERR(r, "cookie lock file open failed.");
285 apr_file_close(file);
289 chxj_update_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
297 DBG(r, "start chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
299 file = chxj_cookie_db_lock(r);
301 ERR(r, "mod_chxj: Can't lock cookie db");
302 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
306 retval = apr_dbm_open_ex(&f,
308 chxj_cookie_db_name_create(r, m->cookie_db_dir),
312 if (retval != APR_SUCCESS) {
313 ERR(r, "could not open dbm (type %s) auth file: %s",
315 chxj_cookie_db_name_create(r,m->cookie_db_dir));
316 chxj_cookie_db_unlock(r, file);
317 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
326 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
327 dbmkey.dsize = strlen(cookie_id);
332 dbmval.dptr = apr_pstrdup(r->pool, store_string);
333 dbmval.dsize = strlen(store_string);
338 retval = apr_dbm_store(f, dbmkey, dbmval);
339 if (retval != APR_SUCCESS) {
340 ERR(r, "Cannot store Cookie data to DBM file `%s'",
341 chxj_cookie_db_name_create(r, m->cookie_db_dir));
343 chxj_cookie_db_unlock(r, file);
344 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
348 chxj_cookie_db_unlock(r, file);
349 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
355 chxj_load_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
357 char *load_string = NULL;
364 DBG(r, "REQ[%X] start chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
365 file = chxj_cookie_db_lock(r);
367 ERR(r, "REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
368 DBG(r, "REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
372 retval = apr_dbm_open_ex(&f,
374 chxj_cookie_db_name_create(r, m->cookie_db_dir),
378 if (retval != APR_SUCCESS) {
381 "%s:%d could not open dbm (type %s) auth file: %s (%d:%s)",
385 chxj_cookie_db_name_create(r, m->cookie_db_dir),
387 apr_strerror(retval, errstr, 255));
388 chxj_cookie_db_unlock(r, file);
389 DBG(r, "TO_REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
396 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
397 dbmkey.dsize = strlen(dbmkey.dptr);
399 if (apr_dbm_exists(f, dbmkey)) {
400 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
401 if (retval != APR_SUCCESS) {
404 "%s:%d could not fetch dbm (type %s) auth file: %s(%d:%s)",
408 chxj_cookie_db_name_create(r, m->cookie_db_dir),
410 apr_strerror(retval, errstr, 255));
412 chxj_cookie_db_unlock(r, file);
413 DBG(r, "REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
416 load_string = apr_palloc(r->pool, dbmval.dsize+1);
418 memset(load_string, 0, dbmval.dsize+1);
419 memcpy(load_string, dbmval.dptr, dbmval.dsize);
422 DBG(r, "REQ[%X] Not Found cookie_id:[%s]", TO_ADDR(r), cookie_id);
423 load_string = apr_pstrdup(r->pool, "");
426 chxj_cookie_db_unlock(r, file);
427 DBG(r, "REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
433 chxj_delete_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
440 DBG(r, "start chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
441 file = chxj_cookie_db_lock(r);
443 ERR(r, "mod_chxj: Can't lock cookie db");
444 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
448 retval = apr_dbm_open_ex(&f,
450 chxj_cookie_db_name_create(r, m->cookie_db_dir),
454 if (retval != APR_SUCCESS) {
456 "could not open dbm (type %s) auth file: %s",
458 chxj_cookie_db_name_create(r,m->cookie_db_dir));
459 chxj_cookie_db_unlock(r, file);
460 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
467 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
468 dbmkey.dsize = strlen(dbmkey.dptr);
469 if (apr_dbm_exists(f, dbmkey)) {
470 apr_dbm_delete(f, dbmkey);
473 chxj_cookie_db_unlock(r, file);
474 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
480 chxj_save_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
489 DBG(r, "start chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
490 file = chxj_cookie_expire_db_lock(r);
492 ERR(r, "mod_chxj: Can't lock cookie db");
493 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
497 retval = apr_dbm_open_ex(&f,
499 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
503 if (retval != APR_SUCCESS) {
504 ERR(r, "could not open dbm (type %s) auth file: %s",
506 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
507 chxj_cookie_expire_db_unlock(r, file);
508 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
515 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
516 dbmkey.dsize = strlen(cookie_id);
522 store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
523 dbmval.dptr = store_string;
524 dbmval.dsize = strlen(store_string);
529 retval = apr_dbm_store(f, dbmkey, dbmval);
530 if (retval != APR_SUCCESS) {
531 ERR(r, "Cannot store Cookie data to DBM file `%s'",
532 chxj_cookie_db_name_create(r, m->cookie_db_dir));
533 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
535 chxj_cookie_expire_db_unlock(r, file);
541 chxj_cookie_expire_db_unlock(r, file);
542 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
549 chxj_delete_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
556 DBG(r, "start chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
557 file = chxj_cookie_expire_db_lock(r);
559 ERR(r, "mod_chxj: Can't lock cookie db");
560 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
563 retval = apr_dbm_open_ex(&f,
565 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
569 if (retval != APR_SUCCESS) {
571 "could not open dbm (type %s) auth file: %s",
573 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
574 chxj_cookie_expire_db_unlock(r, file);
575 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
582 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
583 dbmkey.dsize = strlen(dbmkey.dptr);
584 if (apr_dbm_exists(f, dbmkey)) {
585 apr_dbm_delete(f, dbmkey);
588 chxj_cookie_expire_db_unlock(r, file);
589 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
596 chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m)
605 DBG(r, "start chxj_cookie_expire_gc_dbm()");
607 file = chxj_cookie_expire_db_lock(r);
609 ERR(r, "mod_chxj: Can't lock cookie db");
610 DBG(r, "end chxj_cookie_expire_gc_dbm()");
614 retval = apr_dbm_open_ex(&f,
616 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
620 if (retval != APR_SUCCESS) {
622 "could not open dbm (type %s) auth file: %s",
624 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
625 chxj_cookie_expire_db_unlock(r, file);
626 DBG(r, "end chxj_cookie_expire_gc_dbm()");
633 memset(&dbmkey, 0, sizeof(apr_datum_t));
635 now_time = time(NULL);
637 retval = apr_dbm_firstkey(f, &dbmkey);
638 if (retval == APR_SUCCESS) {
639 DBG(r, "firstkey=[%.*s]", (int)dbmkey.dsize, dbmkey.dptr);
646 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
647 if (retval != APR_SUCCESS) {
650 tmp = apr_palloc(r->pool, dbmval.dsize+1);
651 memset(tmp, 0, dbmval.dsize+1);
652 memcpy(tmp, dbmval.dptr, dbmval.dsize);
655 val_time = atoi(tmp);
657 if (m->cookie_timeout == 0)
658 cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
660 cmp_time = now_time - m->cookie_timeout;
662 DBG(r, "m->cookie_timeout=[%d]", (int)m->cookie_timeout);
663 DBG(r, "key=[%.*s] cmp_time=[%d] val_time=[%d]", (int)dbmkey.dsize, dbmkey.dptr, cmp_time, val_time);
664 if (cmp_time >= val_time) {
665 apr_dbm_delete(f, dbmkey);
667 old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
668 memset(old_cookie_id, 0, dbmkey.dsize+1);
669 memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
671 chxj_delete_cookie(r,old_cookie_id);
672 DBG(r, "detect timeout cookie [%s]", old_cookie_id);
675 retval = apr_dbm_nextkey(f, &dbmkey);
676 } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
680 chxj_cookie_expire_db_unlock(r, file);
681 DBG(r, "end chxj_cookie_expire_gc_dbm()");
687 chxj_cookie_lock_dbm(request_rec *r, mod_chxj_config *UNUSED(m))
689 cookie_lock_t *ret = apr_palloc(r->pool, sizeof(*ret));
690 ret->file = chxj_cookie_db_lock(r);
696 chxj_cookie_unlock_dbm(request_rec *r, cookie_lock_t *lock, mod_chxj_config *UNUSED(m))
698 chxj_cookie_expire_db_unlock(r, lock->file);
699 return 1; /* allways true */