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 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,
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, "%s:%d could not open dbm (type %s) auth file: %s(%d:%s)",
63 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
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' tye:[%s] (%d:%s) key:[%s] val:[%s]",
91 chxj_cookie_db_name_create(r, m->cookie_db_dir),
92 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
94 apr_strerror(retval, errstr, 255),
98 chxj_cookie_db_unlock(r, file);
99 DBG(r, "REQ[%X] end chxj_save_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
104 chxj_cookie_db_unlock(r, file);
105 DBG(r, "REQ[%X] end chxj_save_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
111 chxj_cookie_db_unlock(request_rec *r, apr_file_t *file)
115 rv = apr_file_unlock(file);
116 if (rv != APR_SUCCESS) {
117 ERR(r, "cookie lock file open failed.");
121 apr_file_close(file);
126 chxj_cookie_db_lock(request_rec *r)
130 mod_chxj_config *dconf;
132 dconf = (mod_chxj_config*)chxj_get_module_config(r->per_dir_config, &chxj_module);
134 rv = apr_file_open(&file,
135 chxj_cookie_db_lock_name_create(r, dconf->cookie_db_dir),
136 APR_CREATE|APR_WRITE,
139 if (rv != APR_SUCCESS) {
140 ERR(r, "cookie lock file open failed.");
144 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
145 if (rv != APR_SUCCESS) {
146 ERR(r, "cookie lock file open failed.");
147 apr_file_close(file);
156 chxj_cookie_db_name_create(request_rec *r, const char *dir)
161 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
164 dst = apr_pstrdup(r->pool, dir);
167 if (dst[strlen(dst)-1] != '/') {
168 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_NAME, NULL);
171 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_NAME, NULL);
179 chxj_cookie_db_lock_name_create(request_rec *r, const char *dir)
182 DBG(r, "REQ[%X] start chxj_cookie_db_lock_name_create()", TO_ADDR(r));
185 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
188 dst = apr_pstrdup(r->pool, dir);
190 if (dst[strlen(dst)-1] != '/') {
191 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_LOCK_NAME, NULL);
194 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_LOCK_NAME, NULL);
196 DBG(r, "REQ[%X] end chxj_cookie_db_lock_name_create()", TO_ADDR(r));
203 chxj_cookie_expire_db_name_create(request_rec *r, const char *dir)
208 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
211 dst = apr_pstrdup(r->pool, dir);
214 if (dst[strlen(dst)-1] != '/') {
215 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_NAME, NULL);
218 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_NAME, NULL);
226 chxj_cookie_expire_db_lock_name_create(request_rec *r, const char *dir)
231 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
234 dst = apr_pstrdup(r->pool, dir);
236 if (dst[strlen(dst)-1] != '/') {
237 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
240 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
248 chxj_cookie_expire_db_lock(request_rec *r)
252 mod_chxj_config *dconf;
254 dconf = (mod_chxj_config *)chxj_get_module_config(r->per_dir_config, &chxj_module);
256 rv = apr_file_open(&file,
257 chxj_cookie_expire_db_lock_name_create(r, dconf->cookie_db_dir),
258 APR_CREATE|APR_WRITE,
261 if (rv != APR_SUCCESS) {
262 ERR(r, "cookie lock file open failed.");
266 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
267 if (rv != APR_SUCCESS) {
268 ERR(r, "cookie lock file open failed.");
269 apr_file_close(file);
278 chxj_cookie_expire_db_unlock(request_rec *r, apr_file_t *file)
282 rv = apr_file_unlock(file);
283 if (rv != APR_SUCCESS) {
284 ERR(r, "cookie lock file open failed.");
288 apr_file_close(file);
292 chxj_update_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
300 DBG(r, "start chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
302 file = chxj_cookie_db_lock(r);
304 ERR(r, "mod_chxj: Can't lock cookie db");
305 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
309 retval = apr_dbm_open_ex(&f,
310 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
311 chxj_cookie_db_name_create(r, m->cookie_db_dir),
315 if (retval != APR_SUCCESS) {
316 ERR(r, "could not open dbm (type %s) auth file: %s",
317 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
318 chxj_cookie_db_name_create(r,m->cookie_db_dir));
319 chxj_cookie_db_unlock(r, file);
320 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
329 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
330 dbmkey.dsize = strlen(cookie_id);
335 dbmval.dptr = apr_pstrdup(r->pool, store_string);
336 dbmval.dsize = strlen(store_string);
341 retval = apr_dbm_store(f, dbmkey, dbmval);
342 if (retval != APR_SUCCESS) {
344 ERR(r, "%s:%d Cannot store Cookie data to DBM file `%s' tye:[%s] (%d:%s) key:[%s] val:[%s]",
347 chxj_cookie_db_name_create(r, m->cookie_db_dir),
348 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
350 apr_strerror(retval, errstr, 255),
354 chxj_cookie_db_unlock(r, file);
355 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
359 chxj_cookie_db_unlock(r, file);
360 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
366 chxj_load_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
368 char *load_string = NULL;
375 DBG(r, "REQ[%X] start chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
376 file = chxj_cookie_db_lock(r);
378 ERR(r, "REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
379 DBG(r, "REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
383 retval = apr_dbm_open_ex(&f,
384 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
385 chxj_cookie_db_name_create(r, m->cookie_db_dir),
389 if (retval != APR_SUCCESS) {
392 "%s:%d could not open dbm (type %s) auth file: %s (%d:%s)",
395 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
396 chxj_cookie_db_name_create(r, m->cookie_db_dir),
398 apr_strerror(retval, errstr, 255));
399 chxj_cookie_db_unlock(r, file);
400 DBG(r, "TO_REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
407 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
408 dbmkey.dsize = strlen(dbmkey.dptr);
410 if (apr_dbm_exists(f, dbmkey)) {
411 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
412 if (retval != APR_SUCCESS) {
415 "%s:%d could not fetch dbm (type %s) auth file: %s(%d:%s)",
418 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
419 chxj_cookie_db_name_create(r, m->cookie_db_dir),
421 apr_strerror(retval, errstr, 255));
423 chxj_cookie_db_unlock(r, file);
424 DBG(r, "REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
427 load_string = apr_palloc(r->pool, dbmval.dsize+1);
429 memset(load_string, 0, dbmval.dsize+1);
430 memcpy(load_string, dbmval.dptr, dbmval.dsize);
433 DBG(r, "REQ[%X] Not Found cookie_id:[%s]", TO_ADDR(r), cookie_id);
434 load_string = apr_pstrdup(r->pool, "");
437 chxj_cookie_db_unlock(r, file);
438 DBG(r, "REQ[%X] end chxj_load_cookie_dbm() cookie_id:[%s]", TO_ADDR(r), cookie_id);
444 chxj_delete_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
451 DBG(r, "start chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
452 file = chxj_cookie_db_lock(r);
454 ERR(r, "mod_chxj: Can't lock cookie db");
455 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
459 retval = apr_dbm_open_ex(&f,
460 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
461 chxj_cookie_db_name_create(r, m->cookie_db_dir),
465 if (retval != APR_SUCCESS) {
467 "could not open dbm (type %s) auth file: %s",
468 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
469 chxj_cookie_db_name_create(r,m->cookie_db_dir));
470 chxj_cookie_db_unlock(r, file);
471 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
478 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
479 dbmkey.dsize = strlen(dbmkey.dptr);
480 if (apr_dbm_exists(f, dbmkey)) {
481 apr_dbm_delete(f, dbmkey);
484 chxj_cookie_db_unlock(r, file);
485 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
491 chxj_save_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
500 DBG(r, "start chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
501 file = chxj_cookie_expire_db_lock(r);
503 ERR(r, "mod_chxj: Can't lock cookie db");
504 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
508 retval = apr_dbm_open_ex(&f,
509 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
510 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
514 if (retval != APR_SUCCESS) {
515 ERR(r, "could not open dbm (type %s) auth file: %s",
516 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
517 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
518 chxj_cookie_expire_db_unlock(r, file);
519 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
526 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
527 dbmkey.dsize = strlen(cookie_id);
533 store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
534 dbmval.dptr = store_string;
535 dbmval.dsize = strlen(store_string);
540 retval = apr_dbm_store(f, dbmkey, dbmval);
541 if (retval != APR_SUCCESS) {
542 ERR(r, "Cannot store Cookie data to DBM file `%s'",
543 chxj_cookie_db_name_create(r, m->cookie_db_dir));
544 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
546 chxj_cookie_expire_db_unlock(r, file);
552 chxj_cookie_expire_db_unlock(r, file);
553 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
560 chxj_delete_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
567 DBG(r, "start chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
568 file = chxj_cookie_expire_db_lock(r);
570 ERR(r, "mod_chxj: Can't lock cookie db");
571 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
574 retval = apr_dbm_open_ex(&f,
575 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
576 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
580 if (retval != APR_SUCCESS) {
582 "could not open dbm (type %s) auth file: %s",
583 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
584 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
585 chxj_cookie_expire_db_unlock(r, file);
586 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
593 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
594 dbmkey.dsize = strlen(dbmkey.dptr);
595 if (apr_dbm_exists(f, dbmkey)) {
596 apr_dbm_delete(f, dbmkey);
599 chxj_cookie_expire_db_unlock(r, file);
600 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
607 chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m)
616 DBG(r, "start chxj_cookie_expire_gc_dbm()");
618 file = chxj_cookie_expire_db_lock(r);
620 ERR(r, "mod_chxj: Can't lock cookie db");
621 DBG(r, "end chxj_cookie_expire_gc_dbm()");
625 retval = apr_dbm_open_ex(&f,
626 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
627 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
631 if (retval != APR_SUCCESS) {
633 "could not open dbm (type %s) auth file: %s",
634 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
635 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
636 chxj_cookie_expire_db_unlock(r, file);
637 DBG(r, "end chxj_cookie_expire_gc_dbm()");
644 memset(&dbmkey, 0, sizeof(apr_datum_t));
646 now_time = time(NULL);
648 retval = apr_dbm_firstkey(f, &dbmkey);
649 if (retval == APR_SUCCESS) {
650 DBG(r, "firstkey=[%.*s]", (int)dbmkey.dsize, dbmkey.dptr);
657 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
658 if (retval != APR_SUCCESS) {
661 tmp = apr_palloc(r->pool, dbmval.dsize+1);
662 memset(tmp, 0, dbmval.dsize+1);
663 memcpy(tmp, dbmval.dptr, dbmval.dsize);
666 val_time = atoi(tmp);
668 if (m->cookie_timeout == 0)
669 cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
671 cmp_time = now_time - m->cookie_timeout;
673 DBG(r, "m->cookie_timeout=[%d]", (int)m->cookie_timeout);
674 DBG(r, "key=[%.*s] cmp_time=[%d] val_time=[%d]", (int)dbmkey.dsize, dbmkey.dptr, cmp_time, val_time);
675 if (cmp_time >= val_time) {
676 apr_dbm_delete(f, dbmkey);
678 old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
679 memset(old_cookie_id, 0, dbmkey.dsize+1);
680 memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
682 chxj_delete_cookie(r,old_cookie_id);
683 DBG(r, "detect timeout cookie [%s]", old_cookie_id);
686 retval = apr_dbm_nextkey(f, &dbmkey);
687 } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
691 chxj_cookie_expire_db_unlock(r, file);
692 DBG(r, "end chxj_cookie_expire_gc_dbm()");
698 chxj_cookie_lock_dbm(request_rec *r, mod_chxj_config *UNUSED(m))
700 cookie_lock_t *ret = apr_palloc(r->pool, sizeof(*ret));
701 ret->file = chxj_cookie_db_lock(r);
707 chxj_cookie_unlock_dbm(request_rec *r, cookie_lock_t *lock, mod_chxj_config *UNUSED(m))
709 chxj_cookie_expire_db_unlock(r, lock->file);
710 return 1; /* allways true */