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, "REQ[%X] start chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
369 file = chxj_cookie_db_lock(r);
371 ERR(r, "REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
372 DBG(r, "REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), 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) {
385 "%s:%d could not open dbm (type %s) auth file: %s (%d:%s)",
389 chxj_cookie_db_name_create(r, m->cookie_db_dir),
391 apr_strerror(retval, errstr, 255));
392 chxj_cookie_db_unlock(r, file);
393 DBG(r, "TO_REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
400 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
401 dbmkey.dsize = strlen(dbmkey.dptr);
403 if (apr_dbm_exists(f, dbmkey)) {
404 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
405 if (retval != APR_SUCCESS) {
408 "%s:%d could not fetch dbm (type %s) auth file: %s(%d:%s)",
412 chxj_cookie_db_name_create(r, m->cookie_db_dir),
414 apr_strerror(retval, errstr, 255));
416 chxj_cookie_db_unlock(r, file);
417 DBG(r, "REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
420 load_string = apr_palloc(r->pool, dbmval.dsize+1);
422 memset(load_string, 0, dbmval.dsize+1);
423 memcpy(load_string, dbmval.dptr, dbmval.dsize);
426 DBG(r, "REQ[%X] Not Found cookie_id:[%s]", TO_ADDR(r), cookie_id);
427 load_string = apr_pstrdup(r->pool, "");
430 chxj_cookie_db_unlock(r, file);
431 DBG(r, "REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
437 chxj_delete_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
444 DBG(r, "start chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
445 file = chxj_cookie_db_lock(r);
447 ERR(r, "mod_chxj: Can't lock cookie db");
448 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
452 retval = apr_dbm_open_ex(&f,
454 chxj_cookie_db_name_create(r, m->cookie_db_dir),
458 if (retval != APR_SUCCESS) {
460 "could not open dbm (type %s) auth file: %s",
462 chxj_cookie_db_name_create(r,m->cookie_db_dir));
463 chxj_cookie_db_unlock(r, file);
464 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
471 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
472 dbmkey.dsize = strlen(dbmkey.dptr);
473 if (apr_dbm_exists(f, dbmkey)) {
474 apr_dbm_delete(f, dbmkey);
477 chxj_cookie_db_unlock(r, file);
478 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
484 chxj_save_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
493 DBG(r, "start chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
494 file = chxj_cookie_expire_db_lock(r);
496 ERR(r, "mod_chxj: Can't lock cookie db");
497 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
501 retval = apr_dbm_open_ex(&f,
503 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
507 if (retval != APR_SUCCESS) {
508 ERR(r, "could not open dbm (type %s) auth file: %s",
510 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
511 chxj_cookie_expire_db_unlock(r, file);
512 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
519 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
520 dbmkey.dsize = strlen(cookie_id);
526 store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
527 dbmval.dptr = store_string;
528 dbmval.dsize = strlen(store_string);
533 retval = apr_dbm_store(f, dbmkey, dbmval);
534 if (retval != APR_SUCCESS) {
535 ERR(r, "Cannot store Cookie data to DBM file `%s'",
536 chxj_cookie_db_name_create(r, m->cookie_db_dir));
537 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
539 chxj_cookie_expire_db_unlock(r, file);
545 chxj_cookie_expire_db_unlock(r, file);
546 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
553 chxj_delete_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
560 DBG(r, "start chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
561 file = chxj_cookie_expire_db_lock(r);
563 ERR(r, "mod_chxj: Can't lock cookie db");
564 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
567 retval = apr_dbm_open_ex(&f,
569 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
573 if (retval != APR_SUCCESS) {
575 "could not open dbm (type %s) auth file: %s",
577 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
578 chxj_cookie_expire_db_unlock(r, file);
579 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
586 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
587 dbmkey.dsize = strlen(dbmkey.dptr);
588 if (apr_dbm_exists(f, dbmkey)) {
589 apr_dbm_delete(f, dbmkey);
592 chxj_cookie_expire_db_unlock(r, file);
593 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
600 chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m)
609 DBG(r, "start chxj_cookie_expire_gc_dbm()");
611 file = chxj_cookie_expire_db_lock(r);
613 ERR(r, "mod_chxj: Can't lock cookie db");
614 DBG(r, "end chxj_cookie_expire_gc_dbm()");
618 retval = apr_dbm_open_ex(&f,
620 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
624 if (retval != APR_SUCCESS) {
626 "could not open dbm (type %s) auth file: %s",
628 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
629 chxj_cookie_expire_db_unlock(r, file);
630 DBG(r, "end chxj_cookie_expire_gc_dbm()");
637 memset(&dbmkey, 0, sizeof(apr_datum_t));
639 now_time = time(NULL);
641 retval = apr_dbm_firstkey(f, &dbmkey);
642 if (retval == APR_SUCCESS) {
643 DBG(r, "firstkey=[%.*s]", (int)dbmkey.dsize, dbmkey.dptr);
650 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
651 if (retval != APR_SUCCESS) {
654 tmp = apr_palloc(r->pool, dbmval.dsize+1);
655 memset(tmp, 0, dbmval.dsize+1);
656 memcpy(tmp, dbmval.dptr, dbmval.dsize);
659 val_time = atoi(tmp);
661 if (m->cookie_timeout == 0)
662 cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
664 cmp_time = now_time - m->cookie_timeout;
666 DBG(r, "m->cookie_timeout=[%d]", (int)m->cookie_timeout);
667 DBG(r, "key=[%.*s] cmp_time=[%d] val_time=[%d]", (int)dbmkey.dsize, dbmkey.dptr, cmp_time, val_time);
668 if (cmp_time >= val_time) {
669 apr_dbm_delete(f, dbmkey);
671 old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
672 memset(old_cookie_id, 0, dbmkey.dsize+1);
673 memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
675 chxj_delete_cookie(r,old_cookie_id);
676 DBG(r, "detect timeout cookie [%s]", old_cookie_id);
679 retval = apr_dbm_nextkey(f, &dbmkey);
680 } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
684 chxj_cookie_expire_db_unlock(r, file);
685 DBG(r, "end chxj_cookie_expire_gc_dbm()");
691 chxj_cookie_lock_dbm(request_rec *r, mod_chxj_config *UNUSED(m))
693 cookie_lock_t *ret = apr_palloc(r->pool, sizeof(*ret));
694 ret->file = chxj_cookie_db_lock(r);
700 chxj_cookie_unlock_dbm(request_rec *r, cookie_lock_t *lock, mod_chxj_config *UNUSED(m))
702 chxj_cookie_expire_db_unlock(r, lock->file);
703 return 1; /* allways true */