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()",TO_ADDR(r),__func__);
44 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
46 file = chxj_cookie_db_lock(r);
48 ERR(r,"REQ[%X] %s:%d mod_chxj: Can't lock cookie db", TO_ADDR(r),__FILE__,__LINE__);
49 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
50 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
54 retval = apr_dbm_open_ex(&f,
55 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
56 chxj_cookie_db_name_create(r, m->cookie_db_dir),
60 if (retval != APR_SUCCESS) {
62 ERR(r, "REQ[%X] %s:%d could not open dbm (type %s) auth file: %s(%d:%s)",
66 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
67 chxj_cookie_db_name_create(r,m->cookie_db_dir),
69 apr_strerror(retval, errstr, 255));
70 chxj_cookie_db_unlock(r, file);
71 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
72 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
81 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
82 dbmkey.dsize = strlen(cookie_id);
83 dbmval.dptr = apr_pstrdup(r->pool, store_string);
84 dbmval.dsize = strlen(store_string);
89 retval = apr_dbm_store(f, dbmkey, dbmval);
90 if (retval != APR_SUCCESS) {
92 ERR(r, "REQ[%X] %s:%d Cannot store Cookie data to DBM file `%s' tye:[%s] (%d:%s) key:[%s] val:[%s]",
96 chxj_cookie_db_name_create(r, m->cookie_db_dir),
97 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
99 apr_strerror(retval, errstr, 255),
103 chxj_cookie_db_unlock(r, file);
104 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
105 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
110 chxj_cookie_db_unlock(r, file);
111 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
112 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
118 chxj_cookie_db_unlock(request_rec *r, apr_file_t *file)
122 rv = apr_file_unlock(file);
123 if (rv != APR_SUCCESS) {
124 ERR(r, "cookie lock file open failed.");
128 apr_file_close(file);
133 chxj_cookie_db_lock(request_rec *r)
137 mod_chxj_config *dconf;
139 dconf = (mod_chxj_config*)chxj_get_module_config(r->per_dir_config, &chxj_module);
141 rv = apr_file_open(&file,
142 chxj_cookie_db_lock_name_create(r, dconf->cookie_db_dir),
143 APR_CREATE|APR_WRITE,
146 if (rv != APR_SUCCESS) {
147 ERR(r, "cookie lock file open failed.");
151 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
152 if (rv != APR_SUCCESS) {
153 ERR(r, "cookie lock file open failed.");
154 apr_file_close(file);
163 chxj_cookie_db_name_create(request_rec *r, const char *dir)
168 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
171 dst = apr_pstrdup(r->pool, dir);
174 if (dst[strlen(dst)-1] != '/') {
175 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_NAME, NULL);
178 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_NAME, NULL);
186 chxj_cookie_db_lock_name_create(request_rec *r, const char *dir)
189 DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
192 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
195 dst = apr_pstrdup(r->pool, dir);
197 if (dst[strlen(dst)-1] != '/') {
198 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_LOCK_NAME, NULL);
201 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_LOCK_NAME, NULL);
203 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
210 chxj_cookie_expire_db_name_create(request_rec *r, const char *dir)
215 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
218 dst = apr_pstrdup(r->pool, dir);
221 if (dst[strlen(dst)-1] != '/') {
222 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_NAME, NULL);
225 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_NAME, NULL);
233 chxj_cookie_expire_db_lock_name_create(request_rec *r, const char *dir)
238 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
241 dst = apr_pstrdup(r->pool, dir);
243 if (dst[strlen(dst)-1] != '/') {
244 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
247 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
255 chxj_cookie_expire_db_lock(request_rec *r)
259 mod_chxj_config *dconf;
261 dconf = (mod_chxj_config *)chxj_get_module_config(r->per_dir_config, &chxj_module);
263 rv = apr_file_open(&file,
264 chxj_cookie_expire_db_lock_name_create(r, dconf->cookie_db_dir),
265 APR_CREATE|APR_WRITE,
268 if (rv != APR_SUCCESS) {
269 ERR(r, "cookie lock file open failed.");
273 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
274 if (rv != APR_SUCCESS) {
275 ERR(r, "cookie lock file open failed.");
276 apr_file_close(file);
285 chxj_cookie_expire_db_unlock(request_rec *r, apr_file_t *file)
289 rv = apr_file_unlock(file);
290 if (rv != APR_SUCCESS) {
291 ERR(r, "cookie lock file open failed.");
295 apr_file_close(file);
299 chxj_update_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
307 DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
308 DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
310 file = chxj_cookie_db_lock(r);
312 ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
313 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
314 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
318 retval = apr_dbm_open_ex(&f,
319 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
320 chxj_cookie_db_name_create(r, m->cookie_db_dir),
324 if (retval != APR_SUCCESS) {
325 ERR(r,"REQ[%X] could not open dbm (type %s) auth file: %s",
327 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
328 chxj_cookie_db_name_create(r,m->cookie_db_dir));
329 chxj_cookie_db_unlock(r, file);
330 DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
331 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
340 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
341 dbmkey.dsize = strlen(cookie_id);
346 dbmval.dptr = apr_pstrdup(r->pool, store_string);
347 dbmval.dsize = strlen(store_string);
352 retval = apr_dbm_store(f, dbmkey, dbmval);
353 if (retval != APR_SUCCESS) {
355 ERR(r,"REQ[%X] %s:%d Cannot store Cookie data to DBM file `%s' tye:[%s] (%d:%s) key:[%s] val:[%s]",
359 chxj_cookie_db_name_create(r, m->cookie_db_dir),
360 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
362 apr_strerror(retval, errstr, 255),
366 chxj_cookie_db_unlock(r, file);
367 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
368 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
372 chxj_cookie_db_unlock(r, file);
373 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
374 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
380 chxj_load_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
382 char *load_string = NULL;
389 DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
390 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
391 file = chxj_cookie_db_lock(r);
393 ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db", TO_ADDR(r));
394 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
395 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
399 retval = apr_dbm_open_ex(&f,
400 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
401 chxj_cookie_db_name_create(r, m->cookie_db_dir),
405 if (retval != APR_SUCCESS) {
408 "REQ[%X] %s:%d could not open dbm (type %s) auth file: %s (%d:%s)",
412 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
413 chxj_cookie_db_name_create(r, m->cookie_db_dir),
415 apr_strerror(retval, errstr, 255));
416 chxj_cookie_db_unlock(r, file);
417 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
418 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
425 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
426 dbmkey.dsize = strlen(dbmkey.dptr);
428 if (apr_dbm_exists(f, dbmkey)) {
429 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
430 if (retval != APR_SUCCESS) {
433 "REQ[%X] %s:%d could not fetch dbm (type %s) auth file: %s(%d:%s)",
437 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
438 chxj_cookie_db_name_create(r, m->cookie_db_dir),
440 apr_strerror(retval, errstr, 255));
442 chxj_cookie_db_unlock(r, file);
443 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
444 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
447 load_string = apr_palloc(r->pool, dbmval.dsize+1);
449 memset(load_string, 0, dbmval.dsize+1);
450 memcpy(load_string, dbmval.dptr, dbmval.dsize);
453 DBG(r, "REQ[%X] Not Found cookie_id:[%s]", TO_ADDR(r), cookie_id);
454 load_string = apr_pstrdup(r->pool, "");
457 chxj_cookie_db_unlock(r, file);
458 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r), cookie_id);
459 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
465 chxj_delete_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
472 DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
473 DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
474 file = chxj_cookie_db_lock(r);
476 ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
477 DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
478 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
482 retval = apr_dbm_open_ex(&f,
483 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
484 chxj_cookie_db_name_create(r, m->cookie_db_dir),
488 if (retval != APR_SUCCESS) {
490 "REQ[%X] could not open dbm (type %s) auth file: %s",
492 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
493 chxj_cookie_db_name_create(r,m->cookie_db_dir));
494 chxj_cookie_db_unlock(r, file);
495 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
496 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
503 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
504 dbmkey.dsize = strlen(dbmkey.dptr);
505 if (apr_dbm_exists(f, dbmkey)) {
506 apr_dbm_delete(f, dbmkey);
509 chxj_cookie_db_unlock(r, file);
510 DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
511 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
517 chxj_save_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
526 DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
527 DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
528 file = chxj_cookie_expire_db_lock(r);
530 ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
531 DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
532 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
536 retval = apr_dbm_open_ex(&f,
537 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
538 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
542 if (retval != APR_SUCCESS) {
543 ERR(r, "REQ[%X] could not open dbm (type %s) auth file: %s",
545 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
546 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
547 chxj_cookie_expire_db_unlock(r, file);
548 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
549 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
556 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
557 dbmkey.dsize = strlen(cookie_id);
563 store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
564 dbmval.dptr = store_string;
565 dbmval.dsize = strlen(store_string);
570 retval = apr_dbm_store(f, dbmkey, dbmval);
571 if (retval != APR_SUCCESS) {
572 ERR(r,"REQ[%X] Cannot store Cookie data to DBM file `%s'",
574 chxj_cookie_db_name_create(r, m->cookie_db_dir));
575 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
577 chxj_cookie_expire_db_unlock(r, file);
578 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
584 chxj_cookie_expire_db_unlock(r, file);
585 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
586 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
593 chxj_delete_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
600 DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
601 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
602 file = chxj_cookie_expire_db_lock(r);
604 ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
605 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
606 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
609 retval = apr_dbm_open_ex(&f,
610 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
611 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
615 if (retval != APR_SUCCESS) {
617 "REQ[%X] could not open dbm (type %s) auth file: %s",
619 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
620 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
621 chxj_cookie_expire_db_unlock(r, file);
622 DBG(r,"REQ[%X] cookie_id:[%s]", TO_ADDR(r),cookie_id);
623 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
630 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
631 dbmkey.dsize = strlen(dbmkey.dptr);
632 if (apr_dbm_exists(f, dbmkey)) {
633 apr_dbm_delete(f, dbmkey);
636 chxj_cookie_expire_db_unlock(r, file);
637 DBG(r,"REQ[%X] cookie_id:[%s]",TO_ADDR(r),cookie_id);
638 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
645 chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m)
654 DBG(r,"REQ[%X] start %s()",TO_ADDR(r),__func__);
656 file = chxj_cookie_expire_db_lock(r);
658 ERR(r,"REQ[%X] mod_chxj: Can't lock cookie db",TO_ADDR(r));
659 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
663 retval = apr_dbm_open_ex(&f,
664 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
665 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
669 if (retval != APR_SUCCESS) {
671 "REQ[%X] could not open dbm (type %s) auth file: %s",
673 (m->cookie_dbm_type) ? m->cookie_dbm_type : "default",
674 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
675 chxj_cookie_expire_db_unlock(r, file);
676 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
683 memset(&dbmkey, 0, sizeof(apr_datum_t));
685 now_time = time(NULL);
687 retval = apr_dbm_firstkey(f, &dbmkey);
688 if (retval == APR_SUCCESS) {
689 DBG(r,"REQ[%X] firstkey=[%.*s]", TO_ADDR(r),(int)dbmkey.dsize, dbmkey.dptr);
696 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
697 if (retval != APR_SUCCESS) {
700 tmp = apr_palloc(r->pool, dbmval.dsize+1);
701 memset(tmp, 0, dbmval.dsize+1);
702 memcpy(tmp, dbmval.dptr, dbmval.dsize);
705 val_time = atoi(tmp);
707 if (m->cookie_timeout == 0)
708 cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
710 cmp_time = now_time - m->cookie_timeout;
712 DBG(r,"REQ[%X] m->cookie_timeout=[%d]", TO_ADDR(r),(int)m->cookie_timeout);
713 DBG(r,"REQ[%X] key=[%.*s] cmp_time=[%d] val_time=[%d]", TO_ADDR(r),(int)dbmkey.dsize, dbmkey.dptr, cmp_time, val_time);
714 if (cmp_time >= val_time) {
715 apr_dbm_delete(f, dbmkey);
717 old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
718 memset(old_cookie_id, 0, dbmkey.dsize+1);
719 memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
721 chxj_delete_cookie(r,old_cookie_id);
722 DBG(r,"REQ[%X] detect timeout cookie [%s]", TO_ADDR(r),old_cookie_id);
725 retval = apr_dbm_nextkey(f, &dbmkey);
726 } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
730 chxj_cookie_expire_db_unlock(r, file);
731 DBG(r,"REQ[%X] end %s()",TO_ADDR(r),__func__);
737 chxj_cookie_lock_dbm(request_rec *r, mod_chxj_config *UNUSED(m))
739 cookie_lock_t *ret = apr_palloc(r->pool, sizeof(*ret));
740 ret->file = chxj_cookie_db_lock(r);
746 chxj_cookie_unlock_dbm(request_rec *r, cookie_lock_t *lock, mod_chxj_config *UNUSED(m))
748 chxj_cookie_expire_db_unlock(r, lock->file);
749 return 1; /* allways true */