2 * Copyright (C) 2005-2008 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) {
59 ERR(r, "could not open dbm (type %s) auth file: %s",
61 chxj_cookie_db_name_create(r,m->cookie_db_dir));
62 chxj_cookie_db_unlock(r, file);
63 DBG(r, "end chxj_save_cookie_dbm() cookie_id:[%s]", cookie_id);
72 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
73 dbmkey.dsize = strlen(cookie_id);
74 dbmval.dptr = apr_pstrdup(r->pool, store_string);
75 dbmval.dsize = strlen(store_string);
80 retval = apr_dbm_store(f, dbmkey, dbmval);
81 if (retval != APR_SUCCESS) {
82 ERR(r, "Cannot store Cookie data to DBM file `%s'",
83 chxj_cookie_db_name_create(r, m->cookie_db_dir));
85 chxj_cookie_db_unlock(r, file);
86 DBG(r, "end chxj_save_cookie_dbm() cookie_id:[%s]", cookie_id);
91 chxj_cookie_db_unlock(r, file);
92 DBG(r, "end chxj_save_cookie_dbm() cookie_id:[%s]", cookie_id);
98 chxj_cookie_db_unlock(request_rec *r, apr_file_t *file)
102 rv = apr_file_unlock(file);
103 if (rv != APR_SUCCESS) {
104 ERR(r, "cookie lock file open failed.");
108 apr_file_close(file);
113 chxj_cookie_db_lock(request_rec *r)
117 mod_chxj_config *dconf;
119 dconf = (mod_chxj_config*)chxj_get_module_config(r->per_dir_config, &chxj_module);
121 rv = apr_file_open(&file,
122 chxj_cookie_db_lock_name_create(r, dconf->cookie_db_dir),
123 APR_CREATE|APR_WRITE,
126 if (rv != APR_SUCCESS) {
127 ERR(r, "cookie lock file open failed.");
131 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
132 if (rv != APR_SUCCESS) {
133 ERR(r, "cookie lock file open failed.");
134 apr_file_close(file);
143 chxj_cookie_db_name_create(request_rec *r, const char *dir)
148 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
151 dst = apr_pstrdup(r->pool, dir);
154 if (dst[strlen(dst)-1] != '/') {
155 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_NAME, NULL);
158 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_NAME, NULL);
166 chxj_cookie_db_lock_name_create(request_rec *r, const char *dir)
169 DBG(r, "start chxj_cookie_db_lock_name_create()");
173 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
177 dst = apr_pstrdup(r->pool, dir);
180 DBG(r, "dst[strlen(dst)-1]=[%c]", dst[strlen(dst)-1]);
181 if (dst[strlen(dst)-1] != '/') {
182 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_DB_LOCK_NAME, NULL);
185 dst = apr_pstrcat(r->pool, dst, COOKIE_DB_LOCK_NAME, NULL);
187 DBG(r, "end chxj_cookie_db_lock_name_create()");
194 chxj_cookie_expire_db_name_create(request_rec *r, const char *dir)
199 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
202 dst = apr_pstrdup(r->pool, dir);
205 if (dst[strlen(dst)-1] != '/') {
206 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_NAME, NULL);
209 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_NAME, NULL);
217 chxj_cookie_expire_db_lock_name_create(request_rec *r, const char *dir)
222 dst = apr_pstrdup(r->pool, DEFAULT_COOKIE_DB_DIR);
225 dst = apr_pstrdup(r->pool, dir);
227 if (dst[strlen(dst)-1] != '/') {
228 dst = apr_pstrcat(r->pool, dst, "/", COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
231 dst = apr_pstrcat(r->pool, dst, COOKIE_EXPIRE_DB_LOCK_NAME, NULL);
239 chxj_cookie_expire_db_lock(request_rec *r)
243 mod_chxj_config *dconf;
245 dconf = (mod_chxj_config *)chxj_get_module_config(r->per_dir_config, &chxj_module);
247 rv = apr_file_open(&file,
248 chxj_cookie_expire_db_lock_name_create(r, dconf->cookie_db_dir),
249 APR_CREATE|APR_WRITE,
252 if (rv != APR_SUCCESS) {
253 ERR(r, "cookie lock file open failed.");
257 rv = apr_file_lock(file,APR_FLOCK_EXCLUSIVE);
258 if (rv != APR_SUCCESS) {
259 ERR(r, "cookie lock file open failed.");
260 apr_file_close(file);
269 chxj_cookie_expire_db_unlock(request_rec *r, apr_file_t *file)
273 rv = apr_file_unlock(file);
274 if (rv != APR_SUCCESS) {
275 ERR(r, "cookie lock file open failed.");
279 apr_file_close(file);
283 chxj_update_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id, const char *store_string)
291 DBG(r, "start chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
293 file = chxj_cookie_db_lock(r);
295 ERR(r, "mod_chxj: Can't lock cookie db");
296 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
300 retval = apr_dbm_open_ex(&f,
302 chxj_cookie_db_name_create(r, m->cookie_db_dir),
306 if (retval != APR_SUCCESS) {
307 ERR(r, "could not open dbm (type %s) auth file: %s",
309 chxj_cookie_db_name_create(r,m->cookie_db_dir));
310 chxj_cookie_db_unlock(r, file);
311 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
320 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
321 dbmkey.dsize = strlen(cookie_id);
326 dbmval.dptr = apr_pstrdup(r->pool, store_string);
327 dbmval.dsize = strlen(store_string);
332 retval = apr_dbm_store(f, dbmkey, dbmval);
333 if (retval != APR_SUCCESS) {
334 ERR(r, "Cannot store Cookie data to DBM file `%s'",
335 chxj_cookie_db_name_create(r, m->cookie_db_dir));
337 chxj_cookie_db_unlock(r, file);
338 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
342 chxj_cookie_db_unlock(r, file);
343 DBG(r, "end chxj_update_cookie_dbm() cookie_id:[%s]", cookie_id);
349 chxj_load_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
351 char *load_string = NULL;
358 DBG(r, "start chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
359 file = chxj_cookie_db_lock(r);
361 ERR(r, "mod_chxj: Can't lock cookie db");
362 DBG(r, "end chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
366 retval = apr_dbm_open_ex(&f,
368 chxj_cookie_db_name_create(r, m->cookie_db_dir),
372 if (retval != APR_SUCCESS) {
374 "could not open dbm (type %s) auth file: %s",
376 chxj_cookie_db_name_create(r, m->cookie_db_dir));
377 chxj_cookie_db_unlock(r, file);
378 DBG(r, "end chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
385 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
386 dbmkey.dsize = strlen(dbmkey.dptr);
388 if (apr_dbm_exists(f, dbmkey)) {
389 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
390 if (retval != APR_SUCCESS) {
392 "could not fetch dbm (type %s) auth file: %s", "default",
393 chxj_cookie_db_name_create(r, m->cookie_db_dir));
395 chxj_cookie_db_unlock(r, file);
396 DBG(r, "end chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
399 load_string = apr_palloc(r->pool, dbmval.dsize+1);
401 memset(load_string, 0, dbmval.dsize+1);
402 memcpy(load_string, dbmval.dptr, dbmval.dsize);
405 chxj_cookie_db_unlock(r, file);
406 DBG(r, "end chxj_load_cookie_dbm() cookie_id:[%s]", cookie_id);
412 chxj_delete_cookie_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
419 DBG(r, "start chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
420 file = chxj_cookie_db_lock(r);
422 ERR(r, "mod_chxj: Can't lock cookie db");
423 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
427 retval = apr_dbm_open_ex(&f,
429 chxj_cookie_db_name_create(r, m->cookie_db_dir),
433 if (retval != APR_SUCCESS) {
435 "could not open dbm (type %s) auth file: %s",
437 chxj_cookie_db_name_create(r,m->cookie_db_dir));
438 chxj_cookie_db_unlock(r, file);
439 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
446 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
447 dbmkey.dsize = strlen(dbmkey.dptr);
448 if (apr_dbm_exists(f, dbmkey)) {
449 apr_dbm_delete(f, dbmkey);
452 chxj_cookie_db_unlock(r, file);
453 DBG(r, "end chxj_delete_cookie_dbm() cookie_id:[%s]", cookie_id);
459 chxj_save_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
468 DBG(r, "start chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
469 file = chxj_cookie_expire_db_lock(r);
471 ERR(r, "mod_chxj: Can't lock cookie db");
472 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
478 retval = apr_dbm_open_ex(&f,
480 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
484 if (retval != APR_SUCCESS) {
485 ERR(r, "could not open dbm (type %s) auth file: %s",
487 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
488 chxj_cookie_expire_db_unlock(r, file);
489 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
496 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
497 dbmkey.dsize = strlen(cookie_id);
503 store_string = apr_psprintf(r->pool, "%d", (int)time(NULL));
504 dbmval.dptr = store_string;
505 dbmval.dsize = strlen(store_string);
510 retval = apr_dbm_store(f, dbmkey, dbmval);
511 if (retval != APR_SUCCESS) {
512 ERR(r, "Cannot store Cookie data to DBM file `%s'",
513 chxj_cookie_db_name_create(r, m->cookie_db_dir));
514 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
516 chxj_cookie_expire_db_unlock(r, file);
522 chxj_cookie_expire_db_unlock(r, file);
523 DBG(r, "end chxj_save_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
530 chxj_delete_cookie_expire_dbm(request_rec *r, mod_chxj_config *m, const char *cookie_id)
537 DBG(r, "start chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
538 file = chxj_cookie_expire_db_lock(r);
540 ERR(r, "mod_chxj: Can't lock cookie db");
541 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
544 retval = apr_dbm_open_ex(&f,
546 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
550 if (retval != APR_SUCCESS) {
552 "could not open dbm (type %s) auth file: %s",
554 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
555 chxj_cookie_expire_db_unlock(r, file);
556 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
563 dbmkey.dptr = apr_pstrdup(r->pool, cookie_id);
564 dbmkey.dsize = strlen(dbmkey.dptr);
565 if (apr_dbm_exists(f, dbmkey)) {
566 apr_dbm_delete(f, dbmkey);
569 chxj_cookie_expire_db_unlock(r, file);
570 DBG(r, "end chxj_delete_cookie_expire_dbm() cookie_id:[%s]", cookie_id);
577 chxj_cookie_expire_gc_dbm(request_rec *r, mod_chxj_config *m)
586 DBG(r, "start chxj_cookie_expire_gc_dbm()");
588 file = chxj_cookie_expire_db_lock(r);
590 ERR(r, "mod_chxj: Can't lock cookie db");
591 DBG(r, "end chxj_cookie_expire_gc_dbm()");
595 retval = apr_dbm_open_ex(&f,
597 chxj_cookie_expire_db_name_create(r, m->cookie_db_dir),
601 if (retval != APR_SUCCESS) {
603 "could not open dbm (type %s) auth file: %s",
605 chxj_cookie_expire_db_name_create(r,m->cookie_db_dir));
606 chxj_cookie_expire_db_unlock(r, file);
607 DBG(r, "end chxj_cookie_expire_gc_dbm()");
614 memset(&dbmkey, 0, sizeof(apr_datum_t));
616 now_time = time(NULL);
618 retval = apr_dbm_firstkey(f, &dbmkey);
619 if (retval == APR_SUCCESS) {
620 DBG(r, "firstkey=[%.*s]", (int)dbmkey.dsize, dbmkey.dptr);
627 retval = apr_dbm_fetch(f, dbmkey, &dbmval);
628 if (retval != APR_SUCCESS) {
631 tmp = apr_palloc(r->pool, dbmval.dsize+1);
632 memset(tmp, 0, dbmval.dsize+1);
633 memcpy(tmp, dbmval.dptr, dbmval.dsize);
636 val_time = atoi(tmp);
638 if (m->cookie_timeout == 0)
639 cmp_time = now_time - DEFAULT_COOKIE_TIMEOUT;
641 cmp_time = now_time - m->cookie_timeout;
643 DBG(r, "m->cookie_timeout=[%d]", (int)m->cookie_timeout);
644 DBG(r, "key=[%.*s] cmp_time=[%d] val_time=[%d]", (int)dbmkey.dsize, dbmkey.dptr, cmp_time, val_time);
645 if (cmp_time >= val_time) {
646 apr_dbm_delete(f, dbmkey);
648 old_cookie_id = apr_palloc(r->pool, dbmkey.dsize+1);
649 memset(old_cookie_id, 0, dbmkey.dsize+1);
650 memcpy(old_cookie_id, dbmkey.dptr, dbmkey.dsize);
652 chxj_delete_cookie(r,old_cookie_id);
653 DBG(r, "detect timeout cookie [%s]", old_cookie_id);
656 retval = apr_dbm_nextkey(f, &dbmkey);
657 } while(retval == APR_SUCCESS && dbmkey.dptr != NULL);
661 chxj_cookie_expire_db_unlock(r, file);
662 DBG(r, "end chxj_cookie_expire_gc_dbm()");