00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "klone_conf.h"
00010 #include <sys/types.h>
00011 #include <sys/stat.h>
00012 #include <sys/time.h>
00013 #include <stdlib.h>
00014 #include <time.h>
00015 #include <ctype.h>
00016 #include <unistd.h>
00017 #include <fcntl.h>
00018 #ifdef SSL_ON
00019 #include <openssl/evp.h>
00020 #include <openssl/hmac.h>
00021 #include <openssl/rand.h>
00022 #include <klone/ccipher.h>
00023 #endif
00024 #include <u/libu.h>
00025 #include <klone/session.h>
00026 #include <klone/request.h>
00027 #include <klone/response.h>
00028 #include <klone/vars.h>
00029 #include <klone/utils.h>
00030 #include <klone/ses_prv.h>
00031 #include <klone/codecs.h>
00032
00033 enum { DEFAULT_SESSION_EXPIRATION = 60*20 };
00034 static const char SID_NAME[] = "klone_sid";
00035
00036
00037 struct save_cb_params_s
00038 {
00039 session_t *ss;
00040 io_t *io;
00041 };
00042
00043 typedef struct save_cb_params_s save_cb_params_t;
00044
00045 int session_module_term(session_opt_t *so)
00046 {
00047 U_FREE(so);
00048
00049 return 0;
00050 }
00051
00052 int session_module_init(u_config_t *config, session_opt_t **pso)
00053 {
00054 int iv;
00055 session_opt_t *so = NULL;
00056 u_config_t *c = NULL;
00057 const char *v;
00058
00059 dbg_err_if (config == NULL);
00060 dbg_err_if (pso == NULL);
00061
00062 dbg_err_sif ((so = u_zalloc(sizeof(session_opt_t))) == NULL);
00063
00064
00065 so->type = SESSION_TYPE_FILE;
00066 so->max_age = DEFAULT_SESSION_EXPIRATION;
00067 so->compress = 0;
00068 so->encrypt = 0;
00069 (void) u_strlcpy(so->name, SID_NAME, sizeof so->name);
00070
00071
00072
00073 if(!u_config_get_subkey(config, "session", &c))
00074 {
00075
00076 if((v = u_config_get_subkey_value(c, "type")) != NULL)
00077 {
00078 if(!strcasecmp(v, "memory"))
00079 so->type = SESSION_TYPE_MEMORY;
00080 else if(!strcasecmp(v, "file"))
00081 so->type = SESSION_TYPE_FILE;
00082 #ifdef SSL_ON
00083 else if(!strcasecmp(v, "client"))
00084 so->type = SESSION_TYPE_CLIENT;
00085 #endif
00086 else
00087 warn_err("config error: bad session type \'%s\'", v);
00088 }
00089
00090
00091 if((v = u_config_get_subkey_value(c, "max_age")) != NULL)
00092 {
00093 dbg_err_ifm (u_atoi(v, &iv), "config error: bad max_age \'%s\'", v);
00094 so->max_age = U_MAX(iv * 60, 60);
00095 }
00096
00097
00098 dbg_err_if(u_config_get_subkey_value_b(c, "compress", 0,
00099 &so->compress));
00100
00101
00102 dbg_err_if(u_config_get_subkey_value_b(c, "encrypt", 0, &so->encrypt));
00103
00104
00105 if ((v = u_config_get_subkey_value(c, "sid_name")) != NULL)
00106 dbg_err_if (u_strlcpy(so->name, v, sizeof so->name));
00107
00108 #ifndef HAVE_LIBZ
00109 if(so->compress)
00110 warn_err("config error: compression is enabled but libz is not "
00111 "linked");
00112 #endif
00113
00114 #ifndef SSL_ON
00115 if(so->encrypt)
00116 warn_err("config error: encryption is enabled but no SSL "
00117 "lib is linked");
00118 #else
00119
00120 #ifdef SSL_OPENSSL
00121
00122 so->cipher = EVP_aes_256_cbc();
00123
00124 EVP_add_cipher(so->cipher);
00125
00126
00127 dbg_err_if(!RAND_bytes(so->cipher_key, CIPHER_KEY_LEN));
00128 dbg_err_if(!RAND_pseudo_bytes(so->cipher_iv, CIPHER_IV_LEN));
00129
00130
00131 dbg_err_if(!RAND_bytes(so->session_key, CIPHER_KEY_LEN));
00132 dbg_err_if(!RAND_pseudo_bytes(so->session_iv, CIPHER_IV_LEN));
00133 #endif
00134
00135 #ifdef SSL_CYASSL
00136
00137 so->cipher = EVP_aes_256_cbc();
00138
00139
00140 dbg_err_if(!RAND_bytes(so->cipher_key, CIPHER_KEY_LEN));
00141 dbg_err_if(!RAND_bytes(so->cipher_iv, CIPHER_IV_LEN));
00142
00143
00144 dbg_err_if(!RAND_bytes(so->session_key, CIPHER_KEY_LEN));
00145 dbg_err_if(!RAND_bytes(so->session_iv, CIPHER_IV_LEN));
00146 #endif
00147
00148 #endif
00149 }
00150
00151
00152 if(so->type == SESSION_TYPE_MEMORY)
00153 warn_err_ifm(session_mem_module_init(c, so),
00154 "in-memory session engine init error");
00155 else if(so->type == SESSION_TYPE_FILE)
00156 warn_err_ifm(session_file_module_init(c, so),
00157 "file session engine init error");
00158 #ifdef SSL_ON
00159 else if(so->type == SESSION_TYPE_CLIENT)
00160 warn_err_ifm(session_client_module_init(c, so),
00161 "client-side session engine init error");
00162 #endif
00163
00164 *pso = so;
00165
00166 return 0;
00167 err:
00168 u_free(so);
00169 return ~0;
00170 }
00171
00172 int session_prv_calc_maxsize(var_t *v, void *p)
00173 {
00174 const char *value = NULL;
00175 size_t *psz = (size_t*)p;
00176
00177 dbg_err_if (v == NULL);
00178 dbg_err_if (var_get_name(v) == NULL);
00179 dbg_err_if (psz == NULL);
00180
00181 #ifdef SSL_ON
00182 if(*psz == 0)
00183 {
00184 *psz = CODEC_CIPHER_BLOCK_LEN * 2;
00185 }
00186 #endif
00187
00188
00189 *psz += 3 * strlen(var_get_name(v)) + 3;
00190
00191
00192 if((value = var_get_value(v)) != NULL)
00193 *psz += 3 * strlen(value) + 1;
00194
00195 return 0;
00196 err:
00197 return ~0;
00198 }
00199
00200 int session_prv_load_from_buf(session_t *ss, char *buf, size_t size)
00201 {
00202 io_t *io = NULL;
00203
00204 dbg_err_if (ss == NULL);
00205 dbg_err_if (buf == NULL);
00206
00207
00208 dbg_err_if(io_mem_create(buf, size, 0, &io));
00209
00210
00211 dbg_err_if(session_prv_load_from_io(ss, io));
00212
00213 io_free(io);
00214
00215 return 0;
00216 err:
00217 if(io)
00218 io_free(io);
00219 return ~0;
00220 }
00221
00222 int session_prv_save_to_buf(session_t *ss, char **pbuf, size_t *psz)
00223 {
00224 io_t *io = NULL;
00225 char *buf = NULL;
00226 size_t sz = 0;
00227
00228 dbg_err_if (ss == NULL);
00229 dbg_err_if (pbuf == NULL);
00230 dbg_err_if (psz == NULL);
00231
00232
00233
00234 vars_foreach(ss->vars, session_prv_calc_maxsize, (void*)&sz);
00235
00236
00237 buf = u_malloc(sz);
00238 dbg_err_if(buf == NULL);
00239
00240
00241 dbg_err_if(io_mem_create(buf, sz, 0, &io));
00242
00243
00244 dbg_err_if(session_prv_save_to_io(ss, io));
00245
00246
00247
00248
00249 dbg_err_if(io_codecs_remove(io));
00250
00251
00252 sz = io_tell(io);
00253
00254 io_free(io);
00255 io = NULL;
00256
00257 *pbuf = buf;
00258 *psz = sz;
00259
00260 return 0;
00261 err:
00262 if(io)
00263 io_free(io);
00264 U_FREE(buf);
00265 return ~0;
00266 }
00267
00268
00269 static int session_is_good_id(const char *id)
00270 {
00271 const char *p;
00272
00273 dbg_return_if (id == NULL, 0);
00274 dbg_return_if (strlen(id) != SESSION_ID_LENGTH, 0);
00275
00276 for (p = id; *p != '\0'; ++p)
00277 {
00278 if (!isxdigit(*p))
00279 return 0;
00280 }
00281
00282 return 1;
00283 }
00284
00285 static int session_set_filename(session_t *ss)
00286 {
00287 const char *a = NULL;
00288
00289 dbg_return_if (ss->id[0] == '\0', ~0);
00290
00291 dbg_err_if((a = request_get_addr(ss->rq)) == NULL);
00292
00293 dbg_err_if(u_path_snprintf(ss->filename, U_FILENAME_MAX,
00294 U_PATH_SEPARATOR, "%s/klone_sess_%s_%s", ss->so->path, ss->id, a));
00295
00296 return 0;
00297 err:
00298 return ~0;
00299 }
00300
00301 static int session_gen_id(session_t *ss)
00302 {
00303 char buf[256 + 1];
00304 struct timeval tv;
00305
00306 dbg_err_if (ss == NULL);
00307
00308
00309 ss->id[0] = '\0';
00310
00311
00312 dbg_err_sif (gettimeofday(&tv, NULL) == -1);
00313
00314 dbg_err_if (u_snprintf(buf, sizeof buf, "%lu%u%lu%d",
00315 (unsigned long) tv.tv_sec, (unsigned int) getpid(),
00316 (unsigned long) tv.tv_usec, rand()));
00317
00318 dbg_err_if (u_md5(buf, strlen(buf), ss->id));
00319
00320
00321 dbg_err_if (response_set_cookie(ss->rs, ss->so->name, NULL,
00322 0, NULL, NULL, 0));
00323
00324
00325 dbg_err_if (response_set_cookie(ss->rs, ss->so->name, ss->id,
00326 0, NULL, NULL, 0));
00327
00328 return 0;
00329 err:
00330 return ~0;
00331 }
00332
00333 int session_prv_set_id(session_t *ss, const char *sid)
00334 {
00335 dbg_return_if (ss == NULL, ~0);
00336
00337
00338 if (sid && session_is_good_id(sid))
00339 dbg_err_if (u_snprintf(ss->id, sizeof ss->id, "%s", sid));
00340 else
00341 dbg_err_if (session_gen_id(ss));
00342
00343
00344 dbg_err_if (session_set_filename(ss));
00345
00346 return 0;
00347 err:
00348 return ~0;
00349 }
00350
00351 int session_priv_set_id(session_t *ss, const char *sid)
00352 {
00353 return session_prv_set_id(ss, sid);
00354 }
00355
00356 int session_load(session_t *ss)
00357 {
00358 dbg_return_if (ss == NULL, ~0);
00359 dbg_return_if (ss->load == NULL, ~0);
00360
00361 return ss->load(ss);
00362 }
00363
00364 int session_save(session_t *ss)
00365 {
00366 dbg_return_if (ss == NULL, ~0);
00367 dbg_return_if (ss->save == NULL, ~0);
00368
00369
00370
00371 if (vars_count(ss->vars) == 0)
00372 return (ss->id[0] == '\0') ? 0 : session_remove(ss);
00373
00374
00375 if (ss->id[0] == '\0')
00376 {
00377
00378 dbg_err_if (session_prv_set_id(ss, NULL));
00379 }
00380
00381 return ss->save(ss);
00382 err:
00383 return ~0;
00384 }
00385
00386 int session_remove(session_t *ss)
00387 {
00388 dbg_return_if (ss == NULL, ~0);
00389 dbg_return_if (ss->remove == NULL, ~0);
00390
00391
00392 response_set_cookie(ss->rs, ss->so->name, NULL, 0, NULL, NULL, 0);
00393
00394 ss->removed = 1;
00395
00396 return ss->remove(ss);
00397 }
00398
00399 int session_prv_init(session_t *ss, request_t *rq, response_t *rs)
00400 {
00401 const char *sid;
00402
00403 dbg_err_if (ss == NULL);
00404 dbg_err_if (rq == NULL);
00405 dbg_err_if (rs == NULL);
00406
00407 dbg_err_if(vars_create(&ss->vars));
00408
00409 ss->rq = rq;
00410 ss->rs = rs;
00411
00412
00413 sid = request_get_cookie(ss->rq, ss->so->name);
00414 if(sid)
00415 dbg_err_if(session_prv_set_id(ss, sid));
00416
00417 return 0;
00418 err:
00419 return ~0;
00420 }
00421
00422 int session_prv_load_from_io(session_t *ss, io_t *io)
00423 {
00424 u_string_t *line = NULL;
00425 var_t *v = NULL;
00426 codec_t *unzip = NULL, *decrypt = NULL;
00427 unsigned char key[CODEC_CIPHER_KEY_BUFSZ];
00428 size_t ksz;
00429
00430 dbg_return_if (ss == NULL, ~0);
00431 dbg_return_if (io == NULL, ~0);
00432
00433 #ifdef SSL_ON
00434 if(ss->so->encrypt)
00435 {
00436 dbg_err_if(codec_cipher_create(CIPHER_DECRYPT, ss->so->cipher,
00437 ss->so->cipher_key, ss->so->cipher_iv, &decrypt));
00438 dbg_err_if(io_codec_add_tail(io, decrypt));
00439 decrypt = NULL;
00440 }
00441 #else
00442 u_unused_args(key, ksz);
00443 #endif
00444
00445 #ifdef HAVE_LIBZ
00446 if(ss->so->compress)
00447 {
00448 dbg_err_if(codec_gzip_create(GZIP_UNCOMPRESS, &unzip));
00449 dbg_err_if(io_codec_add_tail(io, unzip));
00450 unzip = NULL;
00451 }
00452 #endif
00453
00454 dbg_err_if(u_string_create(NULL, 0, &line));
00455
00456 while(u_getline(io, line) == 0)
00457 {
00458 if(u_string_len(line))
00459 {
00460 dbg_err_if(vars_add_urlvar(ss->vars, u_string_c(line), &v));
00461
00462 #ifdef SSL_ON
00463 if(!strcmp(var_get_name(v), SESSION_KEY_VAR))
00464 {
00465
00466 memset(key, 0, sizeof(key));
00467 ksz = sizeof(key);
00468 dbg_ifb(u_cipher_decrypt(EVP_aes_256_cbc(), ss->so->session_key,
00469 ss->so->session_iv, key, &ksz,
00470 var_get_value(v), var_get_value_size(v)))
00471 {
00472 v = vars_get(ss->vars, SESSION_KEY_VAR);
00473 vars_del(ss->vars, v);
00474 } else {
00475
00476 dbg_err_if(var_set_bin_value(v, key, ksz));
00477 }
00478
00479 }
00480 #endif
00481 }
00482 }
00483
00484
00485 io_codecs_remove(io);
00486
00487 u_string_free(line);
00488
00489 return 0;
00490 err:
00491 if(io)
00492 io_codecs_remove(io);
00493 if(decrypt)
00494 codec_free(decrypt);
00495 if(unzip)
00496 codec_free(unzip);
00497 if(line)
00498 u_string_free(line);
00499 return ~0;
00500 }
00501
00502 int session_free(session_t *ss)
00503 {
00504 if (ss)
00505 {
00506 if(!ss->removed)
00507 dbg_if(session_save(ss));
00508
00509
00510 dbg_if(ss->term(ss));
00511
00512 if(ss->vars)
00513 vars_free(ss->vars);
00514
00515 U_FREE(ss);
00516 }
00517
00518 return 0;
00519 }
00520
00531 vars_t *session_get_vars(session_t *ss)
00532 {
00533 dbg_return_if (ss == NULL, NULL);
00534
00535 return ss->vars;
00536 }
00537
00550 const char *session_get(session_t *ss, const char *name)
00551 {
00552 var_t *v;
00553
00554 dbg_return_if (ss == NULL, NULL);
00555 dbg_return_if (name == NULL, NULL);
00556
00557 v = vars_get(ss->vars, name);
00558 return v ? var_get_value(v): NULL;
00559 }
00560
00571 const char *session_get_id (session_t *ss)
00572 {
00573 dbg_return_if (ss == NULL, NULL);
00574
00575 return ss->id;
00576 }
00577
00590 int session_set(session_t *ss, const char *name, const char *value)
00591 {
00592 var_t *v = NULL;
00593
00594 dbg_err_if (ss == NULL);
00595 dbg_err_if (name == NULL);
00596 dbg_err_if (value == NULL);
00597 dbg_err_if (strlen(name) == 0);
00598
00599 if((v = vars_get(ss->vars, name)) == NULL)
00600 {
00601
00602 dbg_err_if(var_create(name, value, &v));
00603
00604 dbg_err_if(vars_add(ss->vars, v));
00605 } else {
00606
00607 dbg_ifb(var_set_value(v, value))
00608 return ~0;
00609 }
00610
00611 return 0;
00612 err:
00613 if(v)
00614 var_free(v);
00615 return ~0;
00616 }
00617
00630 int session_age(session_t *ss)
00631 {
00632 time_t now;
00633
00634 dbg_return_if (ss == NULL, -1);
00635
00636 now = time(0);
00637
00638
00639 return (int)(now - ss->mtime);
00640 }
00641
00652 int session_clean(session_t *ss)
00653 {
00654 var_t *v = NULL;
00655
00656 dbg_err_if (ss == NULL);
00657
00658 while((v = vars_getn(ss->vars, 0)) != NULL)
00659 {
00660 dbg_err_if(vars_del(ss->vars, v));
00661 var_free(v);
00662 }
00663
00664 return 0;
00665 err:
00666 return ~0;
00667 }
00668
00682 int session_del(session_t *ss, const char *name)
00683 {
00684 var_t *v = NULL;
00685
00686 dbg_err_if (ss == NULL);
00687 dbg_err_if (name == NULL);
00688
00689 dbg_err_if((v = vars_get(ss->vars, name)) == NULL);
00690 dbg_err_if(vars_del(ss->vars, v));
00691 var_free(v);
00692
00693 return 0;
00694 err:
00695 return ~0;
00696 }
00697
00698 #ifdef SSL_ON
00699
00718 int session_set_cipher_key(session_t *ss, const char *data, size_t sz)
00719 {
00720 var_t *v = NULL;
00721
00722 dbg_err_if(ss == NULL);
00723 dbg_err_if(ss->vars == NULL);
00724 dbg_err_if(data == NULL);
00725 dbg_err_if(sz == 0);
00726
00727
00728 if((v = vars_get(ss->vars, SESSION_KEY_VAR)) != NULL)
00729 {
00730 dbg_err_if(vars_del(ss->vars, v));
00731 v = NULL;
00732 }
00733
00734
00735 dbg_err_if(var_bin_create(SESSION_KEY_VAR, data, sz, &v));
00736
00737 dbg_err_if(vars_add(ss->vars, v));
00738 v = NULL;
00739
00740 return 0;
00741 err:
00742 if(v)
00743 var_free(v);
00744 return ~0;
00745 }
00746
00765 int session_get_cipher_key(session_t *ss, char *buf, size_t *psz)
00766 {
00767 var_t *v = NULL;
00768 size_t vsize;
00769
00770 dbg_err_if(ss == NULL);
00771 dbg_err_if(ss->vars == NULL);
00772 dbg_err_if(buf == NULL);
00773 dbg_err_if(psz == 0);
00774 dbg_err_if(*psz == 0);
00775
00776 nop_err_if((v = vars_get(ss->vars, SESSION_KEY_VAR)) == NULL);
00777
00778 vsize = var_get_value_size(v);
00779
00780 dbg_err_if(vsize >= *psz);
00781
00782 memcpy(buf, var_get_value(v), vsize);
00783
00784 *psz = vsize;
00785
00786 return 0;
00787 err:
00788 if(v)
00789 var_free(v);
00790 return ~0;
00791 }
00792
00793 #endif
00794
00795 int session_prv_save_to_io(session_t *ss, io_t *out)
00796 {
00797 save_cb_params_t prm;
00798 codec_t *zip = NULL, *cencrypt = NULL;
00799
00800 dbg_err_if (ss == NULL);
00801 dbg_err_if (out == NULL);
00802
00803 #ifdef HAVE_LIBZ
00804 if(ss->so->compress)
00805 {
00806 dbg_err_if(codec_gzip_create(GZIP_COMPRESS, &zip));
00807 dbg_err_if(io_codec_add_tail(out, zip));
00808 zip = NULL;
00809 }
00810 #endif
00811
00812 #ifdef SSL_ON
00813 if(ss->so->encrypt)
00814 {
00815 dbg_err_if(codec_cipher_create(CIPHER_ENCRYPT, ss->so->cipher,
00816 ss->so->cipher_key, ss->so->cipher_iv, &cencrypt));
00817 dbg_err_if(io_codec_add_tail(out, cencrypt));
00818 cencrypt = NULL;
00819 }
00820 #endif
00821
00822
00823 prm.io = out;
00824 prm.ss = ss;
00825
00826 vars_foreach(ss->vars, session_prv_save_var, (void*)&prm);
00827
00828
00829 io_codecs_remove(out);
00830
00831 return 0;
00832 err:
00833 if(out)
00834 io_codecs_remove(out);
00835 if(zip)
00836 codec_free(zip);
00837 if(cencrypt)
00838 codec_free(cencrypt);
00839 return ~0;
00840 }
00841
00842
00843 int session_prv_save_var(var_t *v, void *vp)
00844 {
00845 enum { NAMESZ = 256, VALSZ = 4096 };
00846 char sname[NAMESZ], svalue[VALSZ];
00847 char *uname = sname, *uvalue = svalue;
00848 save_cb_params_t *pprm = (save_cb_params_t*)vp;
00849
00850 unsigned char ekey[CODEC_CIPHER_KEY_BUFSZ];
00851 unsigned char pkey[CODEC_CIPHER_KEY_BUFSZ];
00852 size_t nsz, vsz, eksz, pksz;
00853 int rc = ~0;
00854
00855 dbg_err_if (v == NULL);
00856
00857
00858 memset(sname, 0, NAMESZ);
00859 memset(svalue, 0, VALSZ);
00860
00861
00862 nsz = 1 + 3 * strlen(var_get_name(v));
00863 vsz = 1 + 3 * var_get_value_size(v);
00864
00865 #ifdef SSL_ON
00866 vsz += CODEC_CIPHER_BLOCK_LEN;
00867
00868 #else
00869 u_unused_args(ekey, eksz);
00870 #endif
00871
00872
00873 if(NAMESZ <= nsz)
00874 dbg_err_if((uname = u_zalloc(nsz)) == NULL);
00875
00876
00877 dbg_err_if(u_urlncpy(uname, var_get_name(v), strlen(var_get_name(v)),
00878 URLCPY_ENCODE) <= 0);
00879
00880 if(var_get_value(v))
00881 {
00882
00883 if(VALSZ <= vsz)
00884 dbg_err_if((uvalue = u_zalloc(vsz)) == NULL);
00885
00886 #ifdef SSL_ON
00887 if(!strcmp(var_get_name(v), SESSION_KEY_VAR))
00888 {
00889 memset(pkey, 0, sizeof(pkey));
00890 memset(ekey, 0, sizeof(ekey));
00891
00892
00893
00894 pksz = var_get_value_size(v);
00895
00896 err_err_ifm(pksz != CODEC_CIPHER_KEY_LEN,
00897 "bad encryption key; it must be %u bytes long",
00898 CODEC_CIPHER_KEY_LEN);
00899
00900 memcpy(pkey, var_get_value(v), pksz);
00901
00902 eksz = sizeof(ekey);;
00903
00904
00905 dbg_err_if(u_cipher_encrypt(EVP_aes_256_cbc(),
00906 pprm->ss->so->session_key, pprm->ss->so->session_iv,
00907 ekey, &eksz, pkey, pksz));
00908
00909
00910 dbg_err_if(var_set_bin_value(v, ekey, eksz));
00911 }
00912 #endif
00913
00914 dbg_err_if(u_urlncpy(uvalue, var_get_value(v), var_get_value_size(v),
00915 URLCPY_ENCODE) <= 0);
00916
00917 dbg_err_if(io_printf(pprm->io, "%s=%s\n", uname, uvalue) < 0);
00918 } else
00919 dbg_err_if(io_printf(pprm->io, "%s=\n", uname) < 0);
00920
00921 rc = 0;
00922 err:
00923
00924 if(uname && uname != sname)
00925 u_free(uname);
00926
00927 if(uvalue && uvalue != svalue)
00928 u_free(uvalue);
00929
00930 return rc;
00931 }
00932
00933 int session_create(session_opt_t *so, request_t *rq, response_t *rs,
00934 session_t **pss)
00935 {
00936 session_t *ss = NULL;
00937
00938 dbg_err_if (so == NULL);
00939 dbg_err_if (rq == NULL);
00940 dbg_err_if (rs == NULL);
00941 dbg_err_if (pss == NULL);
00942
00943 switch(so->type)
00944 {
00945 case SESSION_TYPE_FILE:
00946 dbg_err_if(session_file_create(so, rq, rs, &ss));
00947 break;
00948 case SESSION_TYPE_MEMORY:
00949 dbg_err_if(session_mem_create(so, rq, rs, &ss));
00950 break;
00951 #ifdef SSL_ON
00952 case SESSION_TYPE_CLIENT:
00953 dbg_err_if(session_client_create(so, rq, rs, &ss));
00954 break;
00955 #endif
00956 default:
00957 warn_err("bad session type");
00958 }
00959
00960
00961 if(ss->id[0] != '\0')
00962 {
00963 (void) session_load(ss);
00964
00965 if (session_age(ss) > so->max_age)
00966 {
00967 u_dbg("session %s expired", ss->id);
00968 (void) session_clean(ss);
00969 (void) session_remove(ss);
00970 }
00971 }
00972
00973 *pss = ss;
00974
00975 return 0;
00976 err:
00977 if(ss)
00978 session_free(ss);
00979 return ~0;
00980 }
00981