apr_status_t mod_but_shm_initialize(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { apr_status_t rv; apr_pool_t *mypool; apr_status_t sts; apr_size_t size; int i; rv = apr_pool_create(&mypool, p); if (rv != APR_SUCCESS) { ERRLOG_SRV_INFO("(SHM) Unable to create client pool for SHM"); return rv; } size = (apr_size_t)MOD_BUT_SESSION_COUNT * sizeof(mod_but_cookie) + apr_rmm_overhead_get(MOD_BUT_SESSION_COUNT + 1); ERRLOG_SRV_INFO("(SHM) Size of the shared memory allocation: %d kBytes", size/1024); sts = apr_shm_create(&cs_shm, size, tmpnam(NULL), p); if (sts != APR_SUCCESS) { ERRLOG_SRV_INFO("(SHM) Failed to create shared memory"); return sts; } else { ERRLOG_SRV_INFO("(SHM) Successfully created shared memory"); } sts = apr_rmm_init(&cs_rmm, NULL, apr_shm_baseaddr_get(cs_shm), size, p); if (sts != APR_SUCCESS) { ERRLOG_SRV_INFO("(SHM) Failed to initialize the RMM segment"); return sts; } else { ERRLOG_SRV_INFO("(SHM) Initialized RMM successfully"); } ERRLOG_SRV_INFO("(SHM) STARTING to malloc offsets in RMM"); off = apr_palloc(p, MOD_BUT_SESSION_COUNT * sizeof(apr_rmm_off_t)); for (i = 0; i < MOD_BUT_SESSION_COUNT; i++) { //ap_log_error(PC_LOG_INFO, s, "mod_but_shm.c: Malloc cs_rmm %d", i); off[i] = apr_rmm_malloc(cs_rmm, sizeof(mod_but_cookie)); } /* * Init of RMM with default values */ ERRLOG_SRV_INFO("(SHM) STARTING to give every session the default values"); for (i = 0; i < MOD_BUT_SESSION_COUNT; i++) { mod_but_cookie *c = apr_rmm_addr_get(cs_rmm, off[i]); apr_cpystrn(c->session_name, "empty", sizeof(c->session_name)); apr_cpystrn(c->session_value, "empty", sizeof(c->session_value)); apr_cpystrn(c->service_list, "empty", sizeof(c->service_list)); c->link_to_cookiestore = -1; c->logon_state = 0; c->logon_flag = 0; // used for redirect to ORIG_URL after successful authentication c->auth_strength = 0; } ERRLOG_SRV_INFO("(SHM) END to give every session the default values"); ERRLOG_SRV_INFO("(SHM) Execution of mod_but_shm_initialize was successfully"); apr_pool_cleanup_register(mypool, NULL, shm_cleanup, apr_pool_cleanup_null); return OK; }
void cleaning_shm_from_expired_session(request_rec *r) { mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module); int y; for (y = 0; y < MOD_BUT_SESSION_COUNT; y++) { mod_but_cookie *c = apr_rmm_addr_get(cs_rmm, off[y]); apr_time_t curtime = apr_time_now(); int tnow = (int)apr_time_sec(curtime); int tcreate = c->session_create_time; int tlastaccess = c->session_last_access_time; if (!apr_strnatcmp(c->session_name, config->cookie_name)) { if ((tnow - tcreate) > config->session_timeout) { ERRLOG_INFO("(SHM) Cleanup Task A: Delta between tnow and tcreate %d at shmoffset %d", tnow-tcreate, y); mod_but_delete_session(y, r); } else { if ((tnow - tlastaccess) > config->session_inactivity_timeout) { ERRLOG_INFO("(SHM) Cleanup Task B: Delta between tnow and tlastaccess %d at shmoffset %d", tnow-tlastaccess, y); mod_but_delete_session(y, r); } } } } }
static void *ssl_scache_shmht_realloc(void *opt_param, void *ptr, size_t size) { SSLModConfigRec *mc = myModConfig((server_rec *)opt_param); apr_rmm_off_t off = apr_rmm_realloc(mc->pSessionCacheDataRMM, ptr, size); return apr_rmm_addr_get(mc->pSessionCacheDataRMM, off); }
/* * Create the required structures in the shared memory segment. * The following stuff goes to the shared memory: * a) Cookie Name * b) Cookie Value * c) First URL (which is later used for redirection) * * Note that it is important to save the unparsed URI here, so that URL encoding is preserved. * If we used the parsed URI here, we'd open up ourselves to a HTTP Response Splitting attack * through CR/LF injection. * * Function "searches" for free space within the shm section, and creates a new shm structure, * containing all relevant information a mod_but session requires. * * Writes SHM offset of newly generated session to shmoffset. * * Returns: * STATUS_OK and SHM offset in shmoffset * STATUS_ESHM if out of SHM space * STATUS_EHACKING if hacking is detected * STATUS_ERROR for all other internal errors */ apr_status_t create_new_shm_session(request_rec *r, char *sid, int *shmoffset) { mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module); int i; for (i = 0; i < MOD_BUT_SESSION_COUNT; i++) { mod_but_cookie *c = apr_rmm_addr_get(cs_rmm, off[i]); ERRLOG_INFO("Existing session name [%s] and value [%s]", c->session_name, c->session_value); if (!apr_strnatcmp(c->session_name, "empty")) { ERRLOG_INFO("Setting-up new SHM session at offset [%d]", i); apr_cpystrn(c->session_name, config->cookie_name, sizeof(c->session_name)); apr_cpystrn(c->session_value, sid, sizeof(c->session_value)); /* Store r->unparsed_uri to prevent HTTP Response Splitting attacks */ apr_cpystrn(c->session_firsturl, r->unparsed_uri, sizeof(c->session_firsturl)); c->session_create_time = (int)apr_time_sec(apr_time_now()); c->session_last_access_time = c->session_create_time; c->link_to_cookiestore=-1; c->logon_state = 0; c->auth_strength = 0; apr_cpystrn(c->service_list, config->service_list_cookie_value, sizeof(c->service_list)); ERRLOG_CRIT("Session original URL is [%s]", c->session_firsturl); ERRLOG_INFO("Session name [%s] value [%s] ctime [%ds]", c->session_name, c->session_value, c->session_create_time); *shmoffset = i; return STATUS_OK; } } ERRLOG_INFO("No empty session slot found; all SHM used up"); return STATUS_ESHM; }
/***************************************************************************** * Cookie Store Functionality */ apr_status_t mod_but_shm_initialize_cookiestore(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { apr_status_t rv; apr_pool_t *mypool; apr_status_t sts; apr_size_t size; int i; rv = apr_pool_create(&mypool, p); if (rv != APR_SUCCESS) { ERRLOG_SRV_INFO("(SHM COOKIESTORE) Unable to create client pool for SHM cookiestore"); return rv; } size = (apr_size_t)MOD_BUT_COOKIESTORE_COUNT * sizeof(mod_but_cookie_cookiestore) + apr_rmm_overhead_get(MOD_BUT_COOKIESTORE_COUNT + 1); ERRLOG_SRV_INFO("(SHM COOKIESTORE) Size of the shared cookiestore memory allocation: %d kBytes", size/1024); sts = apr_shm_create(&cs_shm_cookiestore, size, tmpnam(NULL), p); if (sts != APR_SUCCESS) { ERRLOG_SRV_INFO("(SHM COOKIESTORE) Failed to create shared cookiestore memory"); return sts; } else { ERRLOG_SRV_INFO("(SHM COOKIESTORE) Successfully created shared cookiestore memory"); } sts = apr_rmm_init(&cs_rmm_cookiestore, NULL, apr_shm_baseaddr_get(cs_shm_cookiestore), size, p); if (sts != APR_SUCCESS) { ERRLOG_SRV_INFO("(SHM COOKIESTORE) Failed to initialize the RMM segment"); return sts; } else { ERRLOG_SRV_INFO("(SHM COOKIESTORE) Initialized RMM successfully"); } ERRLOG_SRV_INFO("(SHM COOKIESTORE) STARTING to malloc offsets in RMM"); off_cookiestore = apr_palloc(p, MOD_BUT_COOKIESTORE_COUNT * sizeof(apr_rmm_off_t)); for (i = 0; i < MOD_BUT_COOKIESTORE_COUNT; i++) { //ERRLOG_SRV_INFO("Malloc cs_rmm_cookiestore %d", i); off_cookiestore[i] = apr_rmm_malloc(cs_rmm_cookiestore, sizeof(mod_but_cookie_cookiestore)); } /* * Init of RMM with default values */ ERRLOG_SRV_INFO("(SHM COOKIESTORE) STARTING to give every session the default values"); for (i = 0; i < MOD_BUT_COOKIESTORE_COUNT; i++) { mod_but_cookie_cookiestore *c = apr_rmm_addr_get(cs_rmm_cookiestore, off_cookiestore[i]); apr_cpystrn(c->cookie_name, "empty", sizeof(c->cookie_name)); apr_cpystrn(c->cookie_value, "empty", sizeof(c->cookie_value)); c->cookie_next = -1; c->cookie_before = -1; c->cookie_slot_used = -1; c->location_id = -1; } ERRLOG_SRV_INFO("(SHM COOKIESTORE) END to give every session the default values"); ERRLOG_SRV_INFO("(SHM COOKIESTORE) Execution of mod_but_shm_initialize_cookiestore was successfully"); apr_pool_cleanup_register(mypool, NULL, shm_cleanup_cookiestore, apr_pool_cleanup_null); return OK; }
upload_progress_node_t *store_node(ServerConfig *config, const char *key) { apr_rmm_off_t block = apr_rmm_calloc(config->cache_rmm, sizeof(upload_progress_node_t)); upload_progress_node_t *node; node = block ? (upload_progress_node_t *)apr_rmm_addr_get(config->cache_rmm, block) : NULL; node->next = NULL; if(node == NULL) { return NULL; } block = apr_rmm_calloc(config->cache_rmm, strlen(key)+1); node->key = block ? (char *)apr_rmm_addr_get(config->cache_rmm, block) : NULL; if(node->key != NULL) { sprintf(node->key, "%s\0", key); } return node; }
/* * Renew session. * * Create a new session, copy details from old session to new * session, and delete the old session. */ apr_status_t renew_mod_but_session(request_rec *r, int shmoffold, int *shmoffnew) { apr_status_t rc; apr_rmm_t *cs_rmm = find_cs_rmm(); apr_rmm_off_t *off = find_cs_rmm_off(); mod_but_server_t *config; mod_but_cookie *c_old; mod_but_cookie *c_new; ERRLOG_INFO("Renewing sesssion"); config = ap_get_module_config(r->server->module_config, &but_module); c_old = apr_rmm_addr_get(cs_rmm, off[shmoffold]); rc = create_new_mod_but_session(r, r->headers_out, shmoffnew); if (rc != STATUS_OK) { ERRLOG_CRIT("Failed to create new session"); return rc; } c_new = apr_rmm_addr_get(cs_rmm, off[*shmoffnew]); c_new->session_create_time = c_old->session_create_time; c_new->session_last_access_time = c_old->session_last_access_time; c_new->link_to_cookiestore = c_old->link_to_cookiestore; c_new->logon_state = c_old->logon_state; c_new->logon_flag = c_old->logon_flag; c_new->auth_strength = c_old->auth_strength; apr_cpystrn(c_new->orig_url_before_logon, c_old->orig_url_before_logon, sizeof(c_new->orig_url_before_logon)); apr_cpystrn(c_new->service_list, c_old->service_list, sizeof(c_new->service_list)); c_old->link_to_cookiestore = -1; rc = mod_but_delete_session(shmoffold, r); if (rc != STATUS_OK) { ERRLOG_CRIT("Failed to delete old session"); return rc; } return STATUS_OK; }
apr_status_t upload_progress_cache_init(apr_pool_t *pool, ServerConfig *config) { #if APR_HAS_SHARED_MEMORY apr_status_t result; apr_size_t size; upload_progress_cache_t *cache; apr_rmm_off_t block; if (config->cache_file) { /* Remove any existing shm segment with this name. */ apr_shm_remove(config->cache_file, config->pool); } size = APR_ALIGN_DEFAULT(config->cache_bytes); result = apr_shm_create(&config->cache_shm, size, config->cache_file, config->pool); if (result != APR_SUCCESS) { return result; } /* Determine the usable size of the shm segment. */ size = apr_shm_size_get(config->cache_shm); /* This will create a rmm "handler" to get into the shared memory area */ result = apr_rmm_init(&config->cache_rmm, NULL, apr_shm_baseaddr_get(config->cache_shm), size, config->pool); if (result != APR_SUCCESS) { return result; } apr_pool_cleanup_register(config->pool, config , upload_progress_cache_module_kill, apr_pool_cleanup_null); /* init cache object */ CACHE_LOCK(); block = apr_rmm_calloc(config->cache_rmm, sizeof(upload_progress_cache_t)); cache = block ? (upload_progress_cache_t *)apr_rmm_addr_get(config->cache_rmm, block) : NULL; if(cache == NULL) { CACHE_UNLOCK(); return 0; } cache->head = NULL; config->cache_offset = block; config->cache = cache; CACHE_UNLOCK(); #endif return APR_SUCCESS; }
void cleaning_shm_history_from_expired_session(request_rec *r) { mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module); apr_time_t curtime = apr_time_now(); apr_time_t tnow = apr_time_sec(curtime); int y; for (y = 0; y < MOD_BUT_SESSION_HISTORY_COUNT; y++) { mod_but_cookie_history *c_history = apr_rmm_addr_get(cs_rmm_history, off_history[y]); apr_time_t tdelete = c_history->session_delete_time; if (apr_strnatcmp(c_history->session_value, "empty")) { if ((tnow - tdelete) > config->session_timeout_history) { //ERRLOG_INFO("(SHM HISTORY) Cleaning: Delta between tnow and tdelete %d and session value %s", tnow-tdelete, c_history->session_value); apr_cpystrn(c_history->session_value, "empty", sizeof(c_history->session_value)); c_history->session_delete_time = 0; } } } }
static int but_access(request_rec *r) { // pcre (is session free url) pcre *re = NULL; // the regular expression const char *error; // error text for the failed regex compilation int error_offset; // offset of the regex compilation error, if any int rc = 0; // return code of pcre_exec int re_vector[3072]; // pcre (session_renew in url) pcre *re6 = NULL; // the regular expression const char *error6; // error text for the failed regex compilation int error_offset6; // offset of the regex compilation error, if any int rc6 = 0; // return code of pcre_exec int re_vector6[3072]; // firsturl pcre pcre *re4 = NULL; // the regular expression const char *error4; // error text for the failed regex compilation int error_offset4; // offset of the regex compilation error, if any int rc4 = 0; // return code of pcre_exec int re_vector4[3072]; //firsturl pcre pcre *re5 = NULL; // the regular expression //const char *error5; // error text for the failed regex compilation //int error_offset5; // offset of the regex compilation error, if any int rc5 = 0; // return code of pcre_exec int re_vector5[3072]; // rc = return codes static int rc1 = 0; apr_status_t rc2 = 0; static int rc3 = 0; // shared memory settings int shmoffset = 0; static apr_rmm_t *cs_rmm = NULL; static apr_rmm_off_t *off = NULL; cookie_res *cr; // configuration mod_but const char *cookie_try; char *pshm_offset_number; mod_but_cookie *c; mod_but_dir_t *dconfig; apr_port_t port = 0; char *host = NULL; char *no_cookie_support_url = NULL; char *session_destroy_url = NULL; char *all_shm_space_used_url = NULL; char *default_url = NULL; char *session_expired_url = NULL; char *session_inactivity_timeout_url = NULL; char *session_firsturl = NULL; char *logon_server_url = NULL; char *global_logon_server_url = NULL; char *global_logon_server_url_1 = NULL; char *global_logon_server_url_2 = NULL; char *service_list_error_url = NULL; char *orig_url_before_logon = NULL; char *session_hacking_attempt_url = NULL; ap_log_rerror(PC_LOG_CRIT, r, "mod_but: START"); const char *protocol, *ssl_session_id, *ssl_cipher; mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module); if (config == NULL) { return (int)apr_pstrcat(r->pool, "Illegal server record", NULL, NULL); } // get per-directory configuration dconfig = ap_get_module_config(r->per_dir_config, &but_module); if (dconfig == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: Illegal Directory Config"); } if (!config->enabled) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: mod_but_enabled is not activated"); return DECLINED; } ap_log_rerror(PC_LOG_INFO, r, "mod_but: ========= START V1.0 =========== mod_but hook is executed by apache core"); ap_log_rerror(PC_LOG_INFO, r, "mod_but: Request %s", r->uri); port = ap_get_server_port (r); if ((port != 80) && (port != 443)) { /* because of multiple passes through don't use r->hostname() */ host = (char *)apr_psprintf(r->pool, "%s:%d", ap_get_server_name (r), port); } else { host = (char *)apr_psprintf(r->pool, "%s", ap_get_server_name (r)); } protocol = (char *)ssl_var_lookup(r->pool, r->server, r->connection, r, apr_pstrdup(r->pool, "SSL_PROTOCOL") ); ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE: SSL_PROTOCOL [%s]", protocol); ssl_session_id = (char *)ssl_var_lookup(r->pool, r->server, r->connection, r, apr_pstrdup(r->pool, "SSL_SESSION_ID") ); ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE: SSL_SESSION_ID [%s]", ssl_session_id); ssl_cipher = (char *)ssl_var_lookup(r->pool, r->server, r->connection, r, apr_pstrdup(r->pool, "SSL_CIPHER") ); ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE: SSL_CIPHER [%s]", ssl_cipher); /****************************** PART 1 ******************************************************* Check if mod_but session is required for the requesting URI */ /* The var session_free_url implements a regexp for all URL's, for which mod_but does not require a valid session */ if(config->session_free_url != NULL){ re = pcre_compile(config->session_free_url, 0, &error, &error_offset, NULL); }else{ ap_log_rerror(PC_LOG_INFO, r, "mod_but: PCRE FREE URL STRING IS NULL"); } if (re == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: return code of pcre_compile is NULL"); } rc = pcre_exec(re, NULL, r->uri, strlen(r->uri), 0, 0, re_vector, 3072); // BUT-0: session required (goto BUT-1) if (rc < 0 && rc != PCRE_ERROR_NOMATCH) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: %s ID is required for this URI = %s", config->cookie_name, r->uri); } if (rc == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: PCRE output vector too small (%d)", 3072/3-1); ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with the following URI = %s", r->uri); return DECLINED; } // session not required if (rc > 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE: SESSION FREE URL [%s] - [%s]", config->cookie_name, r->uri); /* Renew Session if in URI is defined as RENEW_URI */ if(config->session_renew_url != NULL){ re6 = pcre_compile(config->session_renew_url, 0, &error6, &error_offset6, NULL); }else{ ap_log_rerror(PC_LOG_INFO, r, "mod_but: PCRE FREE URL STRING IS NULL"); } if (re6 == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: return code of pcre_compile is NULL"); } rc6 = pcre_exec(re6, NULL, r->uri, strlen(r->uri), 0, 0, re_vector6, 3072); if (rc6 < 0 && rc6 != PCRE_ERROR_NOMATCH) { // renew url not found ap_log_rerror(PC_LOG_INFO, r, "mod_but: Renew URL is not called"); } if (rc6 == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: PCRE output vector too small (%d)", 3072/3-1); ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with the following URI = %s", r->uri); return DECLINED; } if (rc6 > 0) { // renew url found!! ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE: RENEW SESSION, because RENEW URL [%s] - [%s]", config->cookie_name, r->uri); shmoffset = create_new_mod_but_session(r); if (shmoffset == -1) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with SHM Creation, DECLINED"); if (config->all_shm_space_used_url == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: MOD_BUT_ALL_SHM_SPACE_USED_URL not configured in httpd.conf"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ all_shm_space_used_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->all_shm_space_used_url ); } else { all_shm_space_used_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->all_shm_space_used_url ); } apr_table_setn(r->err_headers_out, "Location", all_shm_space_used_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED ALL_SHM_SPACE_USED_URL"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (shmoffset == -2) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with SID Creation, DECLINED"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ default_url = (char *)apr_psprintf(r->pool, "https://%s/", host); } else { default_url = (char *)apr_psprintf(r->pool, "http://%s/", host); } apr_table_setn(r->err_headers_out, "Location", default_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED DEFAULT_URL"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED RENEW URL"); return DECLINED; } /****************************** PART 2 ******************************************************* Check of the mod_but session a) mod_but session is not sent by client b) mod_but session sent is invalid c) mod_but session sent is ok The code below will only be executed, if the requesting URI requires a mod_but session (status regexp < 0) */ /* BUT-1 (comming from BUT-0) -> session is required Here we will first parse the request headers for a) MOD_BUT_SESSION (will be unset, because we don't want to have it in the backend) b) FREE COOKIES (will be accepted, if configured in httpd.conf) c) OTHER COOKIES (will be unset) */ if (apr_table_get(r->notes, config->cookie_name)) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE: GET SESSION FROM r->notes [%s]", apr_table_get(r->notes, config->cookie_name)); } else { ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE: DO INITIAL HEADER PARSING r->notes [%s]", apr_table_get(r->notes, config->cookie_name)); cr = apr_palloc(r->pool, sizeof(cookie_res)); cr->r = r; cr->cookie = NULL; apr_table_do(mod_but_analyze_request_headers, cr, r->headers_in, NULL); ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE: mod_but_analyze_request_headers finished"); } ap_log_rerror(PC_LOG_INFO, r, "mod_but: SESSION [%s]", apr_table_get(r->notes, config->cookie_name)); if (apr_table_get(r->notes, config->cookie_name) == NULL) { /* This is PART 2 a) mod_but session is not sent by client */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE: CLIENT DID NOT SEND MOD_BUT_SESSION)"); shmoffset = create_new_mod_but_session(r); if (shmoffset == -1) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with SHM Creation, DECLINED"); if (config->all_shm_space_used_url == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: MOD_BUT_ALL_SHM_SPACE_USED_URL not configured in httpd.conf"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ all_shm_space_used_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->all_shm_space_used_url ); } else { all_shm_space_used_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->all_shm_space_used_url ); } apr_table_setn(r->err_headers_out, "Location", all_shm_space_used_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED ALL_SHM_SPACE_USED_URL"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (shmoffset == -2) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with SID Creation, DECLINED"); return HTTP_INTERNAL_SERVER_ERROR; } /* If client did not send a MOD_BUT session return code rc1 of analyze_request_arguments_for_cookie_test(r) 9900: first client request without __cookie_try in query 9901: second client request with __cookie_try=1 in query 9902: third client request with __cookie_try=2 in query 9903: fouth client request with __cookie_try=3 in query, Redirect to error page 9904: DECLINED */ rc1 = analyze_request_arguments_for_cookie_test(r); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: RETURN VALUE OF COOKIE_TEST ROUTINE %d", rc1); cookie_try = NULL; ap_log_rerror(PC_LOG_INFO, r, "mod_but: rc1 is %d", rc1); // NO COOKIE_TRY in URL if (rc1 == 9900){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: rc1 = 9900 aufgerufen"); //TODO BUT: Use absolute URI for redirection re5 = pcre_compile("\r\n", 0, &error4, &error_offset4, NULL); if (re5 == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: return code of pcre_compile is NULL"); } rc5 = pcre_exec(re5, NULL, r->uri, strlen(r->uri), 0, 0, re_vector5, 3072); if (rc5 < 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: r->uri does not contain CR/LF [%s]", r->uri); if (apr_strnatcmp(ssl_session_id,"")){ cookie_try = (char *)apr_psprintf(r->pool, "https://%s%s?__cookie_try=1", host, r->uri); // uri starts with a "/" } else { cookie_try = (char *)apr_psprintf(r->pool, "http://%s%s?__cookie_try=1", host, r->uri); // uri starts with a "/" } apr_table_setn(r->err_headers_out, "Location", cookie_try); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED COOKIE_TRY; CLIENT SENT R WITHOUT SESSION; REDIRECT TO COOKIE_TRY"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (rc5 < 0 && rc5 != PCRE_ERROR_NOMATCH) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: r->uri does not contain CR/LF [%s]", r->uri); } if (rc5 == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: PCRE output vector too small (%d)", 3072/3-1); ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with pcre CRLF = %s", r->uri); return DECLINED; } if (rc5 > 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: ATTACK!!!! r->uri contains CR/LF [%s]", r->uri); apr_table_setn(r->err_headers_out, "Location", "file:///C:\\<script>alert('Hacking?')</script>"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } } // 1 COOKIE_TRY in URL if (rc1 == 9901){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: rc1 = 9901 aufgerufen"); //TODO BUT: Use absolute URI for redirection if (apr_strnatcmp(ssl_session_id,"")){ cookie_try = (char *)apr_psprintf(r->pool, "https://%s%s?__cookie_try=2", host, r->uri); // uri starts with a "/" } else { cookie_try = (char *)apr_psprintf(r->pool, "http://%s%s?__cookie_try=2", host, r->uri); // uri starts with a "/" } //cookie_try = (char *)apr_psprintf(r->pool, "%s?__cookie_try=2", r->uri); apr_table_setn(r->err_headers_out, "Location", cookie_try); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED COOKIE_TRY=2"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } // 2 COOKIE_TRY in URL if (rc1 == 9902){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: rc1 = 9902 aufgerufen"); //TODO BUT: Use absolute URI for redirection if (apr_strnatcmp(ssl_session_id,"")){ cookie_try = (char *)apr_psprintf(r->pool, "https://%s%s?__cookie_try=3", host, r->uri); // uri starts with a "/" } else { cookie_try = (char *)apr_psprintf(r->pool, "http://%s%s?__cookie_try=3", host, r->uri); // uri starts with a "/" } //cookie_try = (char *)apr_psprintf(r->pool, "%s?__cookie_try=3", r->uri); apr_table_setn(r->err_headers_out, "Location", cookie_try); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED COOKIE_TRY=3"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } // 3 COOKIE_TRY in URL if (rc1 == 9903){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: rc1 = 9903 aufgerufen"); if (apr_strnatcmp(ssl_session_id,"")){ no_cookie_support_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->client_refuses_cookies_url ); } else { no_cookie_support_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->client_refuses_cookies_url ); } apr_table_setn(r->err_headers_out, "Location", no_cookie_support_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED NO_COOKIE_SUPPORT_URL"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } // DECLINED if (rc1 == 9904){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: rc1 = 9904 aufgerufen"); return DECLINED; } }else{ /* If we are here, the client has sent a mod_but session (valid or invalid) */ /* Check if Client Cookie is valid (and in SHM) */ int shm_offset_number = validation_of_client_sent_session(r); ap_log_rerror(PC_LOG_INFO, r, "mod_but: Offset Number is %d", shm_offset_number); if (shm_offset_number == -5540){ /* In this case, the sent session has reached its time out */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: Session timeout reached"); if (config->session_expired_url == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: MOD_BUT_SESSION_TIMEOUT_URL not configured in httpd.conf"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ session_expired_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->session_expired_url ); } else { session_expired_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->session_expired_url ); } apr_table_setn(r->err_headers_out, "Location", session_expired_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED SESSION_EXPIRED"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (shm_offset_number == -5541){ /* In this case, the sent session has reached its inactivity timeout */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: Session inactivity timeout reached"); if (config->session_inactivity_timeout_url == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: MOD_BUT_SESSION_INACTIVITY_TIMEOUT_URL not configured in httpd.conf"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ session_inactivity_timeout_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->session_inactivity_timeout_url ); } else { session_inactivity_timeout_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->session_inactivity_timeout_url ); } apr_table_setn(r->err_headers_out, "Location", session_inactivity_timeout_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED SESSION_INACTIVITY_TIMEOUT_URL"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (shm_offset_number == -5542){ /* In this case, the sent session was in the history cache */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: Session found in history"); if (config->session_expired_url == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: MOD_BUT_SESSION_TIMEOUT_URL not configured in httpd.conf"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ session_expired_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->session_expired_url ); } else { session_expired_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->session_expired_url); } apr_table_setn(r->err_headers_out, "Location", session_expired_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED_SESSION_EXPIRED_URL"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (shm_offset_number == -5543){ /* In this case, the sent session by the client is invalid, guessed, hacked or a shm error on our side */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: -5543 Invalid Session sent by the client"); ap_log_rerror(PC_LOG_INFO, r, "mod_but: config->session_hacking_attempt_url = [%s]", config->session_hacking_attempt_url); if (config->session_hacking_attempt_url == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: MOD_BUT_SESSION_HACKING_ATTEMPT_URL not configured in httpd.conf"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ session_hacking_attempt_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->session_hacking_attempt_url ); } else { session_hacking_attempt_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->session_hacking_attempt_url); } apr_table_setn(r->err_headers_out, "Location", session_hacking_attempt_url); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (shm_offset_number < 0){ /* In this case, something went wrong with the return code */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: CRITICAL ERROR shm_offset_number < 0 "); if (config->session_hacking_attempt_url == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: MOD_BUT_SESSION_HACKING_ATTEMPT_URL not configured in httpd.conf"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ session_hacking_attempt_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->session_hacking_attempt_url ); } else { session_hacking_attempt_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->session_hacking_attempt_url); } apr_table_setn(r->err_headers_out, "Location", session_hacking_attempt_url); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } /* If we are here, the client has sent a valid mod_but session */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: CLIENT SENT VALID MOD_BUT_SESSION"); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: CLIENT SENT VALID MOD_BUT SESSION"); /* We will first check, if the requesting URI asks for the session destroy function This implements the "logout" functionality. */ rc2 = analyze_request_uri_for_session_destroy(r); if (rc2 == 8800){ ap_log_rerror(PC_LOG_INFO, r, "mod_but.c: destroy pattern was not in URI = %s", r->uri); } if (rc2 == 8801){ ap_log_rerror(PC_LOG_INFO, r, "mod_but.c: Problems with the following URI = %s", r->uri); } if (rc2 == 8802){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: SESSION will be destroyed"); delete_mod_but_session(shm_offset_number, r); if (apr_strnatcmp(ssl_session_id,"")){ session_destroy_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->session_destroy_url); } else { session_destroy_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->session_destroy_url); } apr_table_setn(r->err_headers_out, "Location", session_destroy_url); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } /* If we are here, the requesting URI does not want to be destroyed and we analyze the request for the cookie_tests. If we are still in the cookie test phase, we have to give the client the Original URI (from the first request) as redirect */ pshm_offset_number = apr_itoa(r->pool, shm_offset_number); if (pshm_offset_number == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: pshm_offset_number is null!!!"); return HTTP_INTERNAL_SERVER_ERROR; } ap_log_rerror(PC_LOG_INFO, r, "mod_but: WRITE APR: r->notes SHMOFFSET [%s]", pshm_offset_number); apr_table_set(r->notes, "SHMOFFSET", pshm_offset_number); ap_log_rerror(PC_LOG_INFO, r, "mod_but: VOR analyze_request_arguments_for_cookie_test"); rc1 = analyze_request_arguments_for_cookie_test(r); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: RETURN VALUE OF COOKIE_TEST ROUTINE WHEN SESSION IS VALID %d", rc1); ap_log_rerror(PC_LOG_INFO, r, "mod_but: NACH analyze_request_arguments_for_cookie_test"); cs_rmm = find_cs_rmm(); off = find_cs_rmm_off(); c = apr_rmm_addr_get(cs_rmm, off[shm_offset_number]); // cookie is sent by the client, it is a valid session and the requesting URL contains a COOKIE TRY parameter if ((rc1 == 9901)||(rc1 == 9902)||(rc1 == 9903)){ if (c->session_firsturl == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: c->session_firsturl is empty"); return HTTP_INTERNAL_SERVER_ERROR; } ap_log_rerror(PC_LOG_CRIT, r, "mod_but: CLIENT SESSION IS VALID AND COOKIE_TRY IN URL"); re4 = pcre_compile("\r\n", 0, &error4, &error_offset4, NULL); if (re4 == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: return code of pcre_compile is NULL"); } rc4 = pcre_exec(re4, NULL, r->uri, strlen(r->uri), 0, 0, re_vector4, 3072); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: Rc4 contains %d",rc4); if (rc4 < 0) { ap_log_rerror(PC_LOG_CRIT, r, "mod_but: r->uri does not contain CR/LF [%s]", r->uri); if (apr_strnatcmp(ssl_session_id,"")){ session_firsturl = (char *)apr_psprintf(r->pool, "https://%s%s", host, c->session_firsturl); } else { session_firsturl = (char *)apr_psprintf(r->pool, "http://%s%s", host, c->session_firsturl); } apr_table_setn(r->err_headers_out, "Location", session_firsturl); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED_SESSION_FIRSTURL"); r->content_type = NULL; ap_log_rerror(PC_LOG_CRIT, r, "mod_but: AAAAAAAAAAAAAAAA FURSTURL %s", session_firsturl); return HTTP_MOVED_TEMPORARILY; } if (rc4 < 0 && rc4 != PCRE_ERROR_NOMATCH) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: r->uri does not contain CR/LF [%s]", r->uri); if (apr_strnatcmp(ssl_session_id,"")){ session_firsturl = (char *)apr_psprintf(r->pool, "https://%s%s", host, c->session_firsturl); } else { session_firsturl = (char *)apr_psprintf(r->pool, "http://%s%s", host, c->session_firsturl); } apr_table_setn(r->err_headers_out, "Location", session_firsturl); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED_SESSION_FIRSTURL"); r->content_type = NULL; ap_log_rerror(PC_LOG_CRIT, r, "mod_but: AAAAAAAAAAAAAAAA FURSTURL %s", session_firsturl); return HTTP_MOVED_TEMPORARILY; } if (rc4 == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: PCRE output vector too small (%d)", 3072/3-1); ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with pcre CRLF = %s", r->uri); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: BBBBBBBBBBBBBBBBBB"); return DECLINED; } if (rc4 > 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: ATTACK!!!! r->uri contains CR/LF [%s]", r->uri); apr_cpystrn(c->session_firsturl, "ATTACK", sizeof(c->session_firsturl)); apr_table_setn(r->err_headers_out, "Location", session_firsturl); r->content_type = NULL; ap_log_rerror(PC_LOG_CRIT, r, "mod_but: CCCCCCCCCCCCCCCCC"); return HTTP_MOVED_TEMPORARILY; } } ap_log_rerror(PC_LOG_CRIT, r, "mod_but: IF WE ARE HERE, THE REQUEST WILL BE AUTHORIZED (NO COOKIE TRY IN URL)"); /* Now let's do the authorization stuff, if enabled by config */ if (config->authorization_enabled) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: Authorization checks are enabled"); rc3 = do_authorization(shm_offset_number, r); /* if return code 7700: client not logged in yet 7701: client is properly authenticated 7702: authentication is not required for this url 7703: client is properly authenticated, but not authorized 7704: client is properly authenticated, but with too low auth_strength (1) 7705: client is properly authenticated, but with too low auth_strength (2) 7706: DECLINED */ if (rc3 == 7700) { /* If we are here, the requesting URI requires authentication and the client is not logged in yet. */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: URI requres auth, but user not logged in yet"); ap_log_rerror(PC_LOG_INFO, r, "mod_but: Client is not logged in"); ap_log_rerror(PC_LOG_INFO, r, "mod_but: orig_url [%s]", c->orig_url_before_logon); apr_cpystrn(c->orig_url_before_logon, r->uri, sizeof(c->orig_url_before_logon)); ap_log_rerror(PC_LOG_INFO, r, "mod_but: CORE SET ORIG_URL TO %s", c->orig_url_before_logon); c->logon_flag=1; ap_log_rerror(PC_LOG_INFO, r, "mod_but: Set logon_flag to[%d]", c->logon_flag); if (dconfig->logon_server_url){ /* If we are here, a Login SERVER is configured for this Location */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: Our Dir Config is [%s]", dconfig->logon_server_url); if (dconfig->logon_server_url == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: dconfig->logon_server_url is empty"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ logon_server_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, dconfig->logon_server_url); } else { logon_server_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, dconfig->logon_server_url); } apr_table_setn(r->err_headers_out, "Location", logon_server_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED LOGON_SERVER_URL"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; }else{ /* If we are here, no LOGIN SERVER is configured for this Location */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: NULL Our Dir Config is [%s]", dconfig->logon_server_url); if (config->global_logon_server_url == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: config->global_logon_server_url is empty"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ global_logon_server_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->global_logon_server_url); } else { global_logon_server_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->global_logon_server_url); } apr_table_setn(r->err_headers_out, "Location", global_logon_server_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED GLOBAL_LOGON_SERVER_URL"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } } if (rc3 == 7701) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: client is properly authenticated"); } if (rc3 == 7702) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: authentication is not required for this url"); } if (rc3 == 7703) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: Client ist properly authenticated, but not allowed to request the url"); if (apr_strnatcmp(ssl_session_id,"")){ service_list_error_url = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->service_list_error_url); } else { service_list_error_url = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->service_list_error_url); } apr_table_setn(r->err_headers_out, "Location", service_list_error_url); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED SERVICE_LIST_ERROR_URL"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (rc3 == 7704) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: Client authenticated, but auth_strength is too low"); if (config->global_logon_server_url_1 == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: config->global_logon_server_url_1 is empty"); return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ global_logon_server_url_1 = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->global_logon_server_url_1); } else { global_logon_server_url_1 = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->global_logon_server_url_1); } apr_table_setn(r->err_headers_out, "Location", global_logon_server_url_1); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED GLOBAL_LOGON_SERVER_URL 1"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (rc3 == 7705) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: Client authenticated, but auth_strength is too low"); if (config->global_logon_server_url_2 == NULL ){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: config->global_logon_server_url_2 is empty"); r->content_type = NULL; return HTTP_INTERNAL_SERVER_ERROR; } if (apr_strnatcmp(ssl_session_id,"")){ global_logon_server_url_2 = (char *)apr_psprintf(r->pool, "https://%s%s", host, config->global_logon_server_url_2); } else { global_logon_server_url_2 = (char *)apr_psprintf(r->pool, "http://%s%s", host, config->global_logon_server_url_2); } apr_table_setn(r->err_headers_out, "Location", global_logon_server_url_2); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED GLOBAL_LOGON_SERVER_URL 2"); r->content_type = NULL; return HTTP_MOVED_TEMPORARILY; } if (rc3 == 7706) { ap_log_rerror(PC_LOG_INFO, r, "mod_but: service_list PCRE output vector too small"); return DECLINED; } }else{ ap_log_rerror(PC_LOG_INFO, r, "mod_but: Authorization checks are disabled or LOGON is not required"); } /* If we are here, the client is properly authenticated and we start proceeding the request. */ /* This is the callback function, if the user was previously successfully authenticated and the c->logon_flag = 1. The flag was set to 1 couple of lines above, if uri requires authentication but is not authenticated yet. we need to redirect the client to the OrigURL (initial uri, before authentication) */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: LOGON_FLAG [%d]", c->logon_flag); ap_log_rerror(PC_LOG_INFO, r, "mod_but: LOGON_STATE [%d]", c->logon_state); if (c->logon_flag == 1 && c->logon_state == 1){ if (c->orig_url_before_logon != NULL){ ap_log_rerror(PC_LOG_INFO, r, "mod_but: SEND REDIRECT AFTER SUCCESSFUL LOGON"); ap_log_rerror(PC_LOG_INFO, r, "mod_but: REDIRECT TO OrigURL: [%s]", c->orig_url_before_logon); if (apr_strnatcmp(ssl_session_id,"")){ orig_url_before_logon = (char *)apr_psprintf(r->pool, "https://%s%s", host, c->orig_url_before_logon); } else { orig_url_before_logon = (char *)apr_psprintf(r->pool, "http://%s%s", host, c->orig_url_before_logon); } apr_table_setn(r->err_headers_out, "Location", orig_url_before_logon); ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED ORIG_URL BEFORE LOGON"); r->content_type = NULL; c->logon_flag=0; return HTTP_MOVED_TEMPORARILY; }else{ ap_log_rerror(PC_LOG_INFO, r, "mod_but: PROBLEM: ORIG_URL is empty"); } }else{ ap_log_rerror(PC_LOG_INFO, r, "mod_but: LOGON_FLAG or LOGON_STATE 0"); } /* If the cookiestore has some "values", we will include them into the request header ADD Headers into the backend request */ if (c->link_to_cookiestore != -1){ add_headers_into_request_from_cookiestore(r, c->link_to_cookiestore); // now all cookies from the cookiestore are within the r->notes REQUEST_COOKIES if (apr_table_get(r->notes, "REQUEST_COOKIES") != NULL) { apr_table_set(r->headers_in, "Cookie", apr_table_get(r->notes, "REQUEST_COOKIES")); } } /* Ok now we will proceed with the request */ ap_log_rerror(PC_LOG_INFO, r, "mod_but: ========= STOP =========== mod_but hook is executed by apache core"); return OK; } return OK; }
upload_progress_node_t *fetch_node(ServerConfig *config, upload_progress_node_t *node) { return (upload_progress_node_t *)apr_rmm_addr_get(config->cache_rmm, apr_rmm_offset_get(config->cache_rmm, node)); }
/* * Delete session in session shm store * Delete everything in history shm store * Delete everything in cookie shm store * * XXX rewrite this (SHM) */ apr_status_t mod_but_delete_session(int shmoff, request_rec *r) { int i; apr_rmm_t *cs_rmm = find_cs_rmm(); apr_rmm_off_t *off = find_cs_rmm_off(); apr_rmm_t *cs_rmm_history = find_cs_rmm_history(); apr_rmm_off_t *off_history = find_cs_rmm_off_history(); mod_but_cookie *c = apr_rmm_addr_get(cs_rmm, off[shmoff]); for (i = 0; i < MOD_BUT_SESSION_HISTORY_COUNT; i++) { mod_but_cookie_history *c_history = apr_rmm_addr_get(cs_rmm_history, off_history[i]); /* * Searching an empty place in the history shm store and copy the session_value to the history */ if (!apr_strnatcmp(c_history->session_value, "empty")) { /* * If we are here, we have found an empty history shm place and backup * the deleting session into the history store */ apr_cpystrn(c_history->session_value, c->session_value, sizeof(c_history->session_value)); c_history->session_delete_time = (int)apr_time_sec(apr_time_now()); ERRLOG_INFO("Make history of session %s at history SHM offset %d", c_history->session_value, i); /* * Now we have a backup of the session value in the history. * The next step will delete the session in the session shm store to make it free for others */ apr_cpystrn(c->session_name, "empty", sizeof(c->session_name)); apr_cpystrn(c->session_value, "empty", sizeof(c->session_value)); apr_cpystrn(c->session_firsturl, "empty", sizeof(c->session_firsturl)); c->logon_state = 0; c->logon_flag = 0; c->auth_strength = 0; apr_cpystrn(c->orig_url_before_logon, "empty", sizeof(c->orig_url_before_logon)); apr_cpystrn(c->service_list, "empty", sizeof(c->service_list)); if (c->link_to_cookiestore == -1) { ERRLOG_INFO("There is nothing in the cookie store to delete"); } else { ERRLOG_INFO("Start DELETING cookiestore headers at CS offset %d", c->link_to_cookiestore); delete_cookiestore_entries_belonging_to_a_deleting_session(r, c->link_to_cookiestore); } return STATUS_OK; } } /* * If we are here, there was no space left in the SHM history. This is a PROBLEM. * We will delete the session without doing history, but we have at least a log entry */ apr_table_setn(r->notes, "HISTORY_SHM" , "PROBLEM"); ERRLOG_INFO("(SHM HISTORY) All SHM HISTORY is used - Unable to make history of session"); apr_cpystrn(c->session_name, "empty", sizeof(c->session_name)); apr_cpystrn(c->session_value, "empty", sizeof(c->session_value)); apr_cpystrn(c->session_firsturl, "empty", sizeof(c->session_firsturl)); if (c->link_to_cookiestore == -1) { ERRLOG_INFO("There is nothing in the cookie store to delete"); } else { ERRLOG_INFO("Start DELETING cookiestore headers at CS offset %d", c->link_to_cookiestore); delete_cookiestore_entries_belonging_to_a_deleting_session(r, c->link_to_cookiestore); } return STATUS_OK; }
/* * Function returns integer value (shmoffset), if the session is found in the shm section */ apr_status_t mod_but_validate_session(request_rec *r, int *shmoffset) { int i; int y = 0; mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module); apr_rmm_t *cs_rmm = find_cs_rmm(); apr_rmm_off_t *off = find_cs_rmm_off(); apr_rmm_t *cs_rmm_history = find_cs_rmm_history(); apr_rmm_off_t *off_history = find_cs_rmm_off_history(); /* * Cleanup Function (delete *old* sessions from shm) */ for (i = 0; i < MOD_BUT_SESSION_COUNT; i++) { /* * Lets go through the shm to find out, if the session is in our shm store */ mod_but_cookie *c = apr_rmm_addr_get(cs_rmm, off[i]); if (!apr_strnatcmp(c->session_value, apr_table_get(r->notes, config->cookie_name))) { apr_time_t curtime; int tnow; int tcreate; int tlastaccess; /* * If we are here, the client has sent a mod_but session */ ERRLOG_INFO("Found session at SHM [%d]", i); curtime = apr_time_now(); tnow = (int)apr_time_sec(curtime); tcreate = c->session_create_time; tlastaccess = c->session_last_access_time; if ((tnow - tcreate) > config->session_timeout) { ERRLOG_INFO("Delta between tnow and tcreate %d", tnow-tcreate); ERRLOG_CRIT("Deleting - session timeout reached at SHM [%d]", i); mod_but_delete_session(i, r); return STATUS_ETIMEOUT; } else if ((tnow - tlastaccess) > config->session_inactivity_timeout) { ERRLOG_INFO("Delta between tnow and tlastaccess %d", tnow-tlastaccess); ERRLOG_CRIT("Deleting - inactivity timeout reached at SHM [%d]", i); mod_but_delete_session(i, r); return STATUS_EINACTIVE; } else { ERRLOG_INFO("Delta between tnow and tlastaccess %d", tnow-tlastaccess); ERRLOG_INFO("Updating access time of session at SHM [%d]", i); c->session_last_access_time = tnow; } // if we are here, the session is valid, and not timed out yet, so we return the shmoffset ERRLOG_INFO("Verified session at SHM [%d]", i); *shmoffset = i; return STATUS_OK; } } // In this case, the sent session by the client is invalid, guessed, hacked or in the history for (y = 0; y < MOD_BUT_SESSION_HISTORY_COUNT; y++) { mod_but_cookie_history *c_history = apr_rmm_addr_get(cs_rmm_history, off_history[y]); if (!apr_strnatcmp(c_history->session_value, apr_table_get(r->notes, config->cookie_name))) { ERRLOG_INFO("Client Session found in SHM HISTORY %s", c_history->session_value); return STATUS_ETIMEOUT; } } /* * If we are here, the session is not in the normal SHM or in the History SHM. It must be a tamper attempt */ ERRLOG_INFO("Hacking attempt [%s]", apr_table_get(r->notes, config->cookie_name)); return STATUS_EHACKING; }
upload_progress_cache_t *fetch_cache(ServerConfig *config) { return (upload_progress_cache_t *)apr_rmm_addr_get(config->cache_rmm, apr_rmm_offset_get(config->cache_rmm, config->cache)); }
int mod_but_analyze_response_headers(void *result, const char *key, const char *value) { /* This function is called for all HTTP RESPONSE HEADER HTTP/1.1 302 Found Date: Mon, 22 Aug 2005 21:10:45 GMT Set-Cookie: E2=jLllj33EsXhInvgW5KDkMtzB4YcqLy2Eawv1EAbY0K3NGUHczLF1oIrJ7bURyw1; domain=but.ch; path=/; Set-Cookie: TEST=ABC; Set-Cookie: FREECOOKIE=123; Location: /cgi/cgi-bin/printenv?__cookie_try=1 Content-Length: 281 Content-Type: text/html; charset=iso-8859-1 It checks the Set-Cookie headers. */ cookie_res * cr = (cookie_res *) result; request_rec *r = cr->r; apr_rmm_t *cs_rmm = find_cs_rmm(); apr_rmm_off_t *off = find_cs_rmm_off(); mod_but_server_t *config; mod_but_dir_t *dconfig = ap_get_module_config(r->per_dir_config, &but_module); pcre *re; // the regular expression const char *error; // error text for the failed regex compilation int error_offset; // offset of the regex compilation error, if any int rc = 0; // return code of pcre_exec int re_vector[3072]; apr_int64_t num_set_cookie; apr_int64_t auth_strength; char *qa = (char *)apr_pstrdup(r->pool, value); char *p, *last; ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: CALLING OUTPUT FILTER"); config = ap_get_module_config(r->server->module_config, &but_module); if (config == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Illegal server record (output filter)"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Request URI [%s]", r->uri); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Working with SHM offset [%s]", apr_table_get(r->notes, "SHMOFFSET")); re = pcre_compile("cOOkIe", PCRE_CASELESS, &error, &error_offset, NULL); if (re == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: return code of pcre_compile in Cookie Store is NULL"); return DECLINED; } if(key==NULL){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: key is NULL"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } rc = pcre_exec(re, NULL, key, strlen(key), 0, 0, re_vector, 3072); if (rc < 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Set-Cookie was not in ARGS = %s", key); return DECLINED; } if (rc == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: PCRE output vector too small (%d)", 3072/3-1); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Problems with the following ARGS = %s", key); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } if (rc > 0) { char* val1; char* substr; char* key1; mod_but_cookie_cookiestore *csp; apr_rmm_t *cs_rmm_cookiestore; apr_rmm_off_t *off_cookiestore; ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: ====================== FIND SET-COOKIE HEADER ====================="); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Found Set-Cookie [%s]=[%s]", key,value); /* Store Set-Cookie attributes into mod_but_cookie_cookiestore struct */ substr = strchr(value, '=' ); key1 = (char*)apr_pstrndup(r->pool, value, (strlen(value)-strlen(substr)) ); substr++; // now substr points to the value if (strchr(substr,';')) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: OUTPUT_FILTER: COOKIE HAS \";\""); val1 = (char*)apr_pstrndup( r->pool, substr, (strlen(substr)-strlen(strchr(substr,';'))) ); } else { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: OUTPUT_FILTER: COOKIE HAS NO \";\""); val1 = (char*)apr_pstrndup( r->pool, substr, (strlen(substr))); } if (!apr_strnatcmp(key1, "") && !apr_strnatcmp(val1, "")){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unparsed %s - %s", key1, val1); return OK; } csp = apr_palloc(r->pool, sizeof(mod_but_cookie_cookiestore)); apr_cpystrn(csp->cookie_name, key1, sizeof(csp->cookie_name)); apr_cpystrn(csp->cookie_value, val1, sizeof(csp->cookie_value)); if (dconfig == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_authorization.c: Illegal Directory Config (location_id)"); } csp->location_id = dconfig->mod_but_location_id; // remember the location, for which a cookie was set. ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: COOKIE LOCATION ID [%d]", csp->location_id); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: PARSED COOKIENAME AND VALUE [%s]-[%s]", csp->cookie_name, csp->cookie_value); cs_rmm_cookiestore = find_cs_rmm_cookiestore(); off_cookiestore = find_cs_rmm_off_cookiestore(); if(apr_table_get(r->notes, "SHMOFFSET")){ apr_int64_t i = apr_atoi64(apr_table_get(r->notes, "SHMOFFSET")); mod_but_cookie *c = apr_rmm_addr_get(cs_rmm, off[i]); /* 1) LOGON cookie? 2) SERVICE_LIST cookie? 3) FREE COOKIE? 4) MOD_BUT_SESSION? 5) Others */ /* 1) Lets see, if the cookie is a LOGON cookie */ if (!apr_strnatcmp(csp->cookie_name, config->global_logon_auth_cookie_name)){ /* First, we set the logon flag to true */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: FOUND LOGON Header"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Requesting r->uri is: %s", r->uri); re = pcre_compile(config->authorized_logon_url, PCRE_CASELESS, &error, &error_offset, NULL); rc = pcre_exec(re, NULL, r->uri, strlen(r->uri), 0, 0, re_vector, 3072); if (rc < 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: LOGON=ok from unauthorized source - we denied it"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unsetting LOGON=ok from response header"); return DECLINED; } if (rc == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: PCRE output vector too small (%d)", 3072/3-1); return DECLINED; } if (rc > 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: LOGON comes form a trusted/authorized source"); if (!apr_strnatcmp(csp->cookie_value, config->global_logon_auth_cookie_value)){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: LOGON=ok comes form a trusted/authorized source"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: LOGON=ok (set c->logon_state=1)"); c->logon_state=1; apr_table_set(r->notes, "LOGON_STATUS", "OK"); } // unset LOGON cookie from the response header ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unsetting LOGON=ok from response header"); return DECLINED; } } /* 3) Check if we have a FREE Cookie (configured in httpd.conf) We do not store FREE Cookies into the cookie store */ if(config->session_store_free_cookies){ char *temp; ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: MOD_BUT_SESSION_STORE_FREE_COOKIES is configured"); re = pcre_compile(config->session_store_free_cookies, 0, &error, &error_offset, NULL); if (re == NULL) { // ap_log_rerror(PC_LOG_INFO, } temp = apr_pstrcat(r->pool, key1, "=", value, NULL); rc = pcre_exec(re, NULL, temp, strlen(temp), 0, 0, re_vector, 3072); if (rc < 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Set-Cookie is not a FREE COOKIE key = %s | value = %s", key1, value); } if (rc == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: PCRE output vector too small (%d)", 3072/3-1); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Problems with the following ARGS = %s", key1); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } if (rc > 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: FOUND FREE COOKIE [%s] [%s]", key1, value); num_set_cookie = apr_atoi64(apr_table_get(r->notes, "NUM_SET_COOKIE")); num_set_cookie += 1; apr_table_set(r->notes, "NUM_SET_COOKIE", apr_itoa(r->pool, num_set_cookie)); apr_table_set(r->notes, apr_itoa(r->pool, num_set_cookie), value); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter: VALUE IS [%s]", apr_table_get(r->notes, apr_itoa(r->pool, num_set_cookie))); return DECLINED; } } /* 4) If the Cookie is the MOD_BUT_SESSION, we don't want to have that cookie stored in the cookie store This means, that NO backend application is allowed to have the same cookie name as the MOD_BUT_SESSION */ if (!apr_strnatcmp(key1, config->cookie_name)){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Set-Cookie is MOD_BUT_SESSION"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } /* 5) If LOGON=ok, we will store the special meaning cookies in a special way here. */ if (apr_table_get(r->notes, "LOGON_STATUS") != NULL){ if (!apr_strnatcmp(key1, "MOD_BUT_AUTH_STRENGTH")){ auth_strength = apr_atoi64(val1); if ((auth_strength >= 0) || (auth_strength <= 2)) { c->auth_strength=auth_strength; } else { c->auth_strength= 0; // default value, if auth_strength is not parseable or greater than 2 } return DECLINED; } /* Lets see, if the SERVICE_LIST cookie is set */ if (!apr_strnatcmp(csp->cookie_name, config->service_list_cookie_name)){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: FOUND SERVICE LIST Cookiename (Authorization Regex)"); apr_cpystrn(c->service_list, val1, sizeof(c->service_list)); return DECLINED; } if (!apr_strnatcmp(key1, "MOD_BUT_BACKEND_SESSION")){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: FOUND MOD_BUT_BACKEND_SESSION [%s]", value); char *p1 = NULL; char *p2 = NULL; char *p3 = NULL; char *p11 = NULL; char *p21 = NULL; char *p31 = NULL; for(p = (char *)apr_strtok(qa, "; ", &last); p != NULL; p = (char *)apr_strtok(NULL, "; ", &last)) { p1 = strstr(p, "bname"); if(p1){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bname found [%s]", p1); p1 += strlen("bname"); if(*p1 == '=') { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bname [%s]", (char *)apr_pstrdup(r->pool, p1+1)); p11 = apr_pstrdup(r->pool, p1+1); } } p2 = strstr(p, "bvalue"); if(p2){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bvalue [%s]", p2); p2 += strlen("bvalue"); if(*p2 == '=') { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bvalue [%s]", (char *)apr_pstrdup(r->pool, p2+1)); p21 = apr_pstrdup(r->pool, p2+1); } } p3 = strstr(p, "bclearance"); if(p3){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bclearance [%s]", p3); p3 += strlen("bclearance"); if(*p3 == '=') { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bclearance [%s]", (char *)apr_pstrdup(r->pool, p3+1)); p31 = apr_pstrdup(r->pool, p3+1); } } } ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bname found [%s]=[%s] CLEAR [%s]", p11,p21,p31); for(p31 = apr_strtok(p31, ",", &last); p31 != NULL; p31 = apr_strtok(NULL, ",", &last)) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: P31 = [%s]", p31); apr_cpystrn(csp->cookie_name, p11, sizeof(csp->cookie_name)); apr_cpystrn(csp->cookie_value, p21, sizeof(csp->cookie_value)); csp->location_id = apr_atoi64(p31); if (c->link_to_cookiestore == -1){ /* Here we have to update the c->link_to_cookiestore */ int cookiestore_offset = find_empty_cookiestore_slot(r); if (cookiestore_offset >= 0){ mod_but_cookie_cookiestore *cs; /* If we are here, we found an empty cookiestore shm storage we can put our stuff into */ cs = apr_rmm_addr_get(cs_rmm_cookiestore, off_cookiestore[cookiestore_offset]); apr_cpystrn(cs->cookie_name, p11, sizeof(cs->cookie_name)); apr_cpystrn(cs->cookie_value, p21, sizeof(cs->cookie_value)); c->link_to_cookiestore = cookiestore_offset; cs->location_id = apr_atoi64(p31); }else{ /* If we are here, we did not have more cookiestore shm */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unable finding new cookiestore slot"); apr_table_set(r->notes, "CS_SHM" , "PROBLEM"); } } else { int status; // if we are here, we are not the first cookie to be saved. status = store_cookie_in_cookiestore(r, c->link_to_cookiestore, csp); if (status == 30){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: All Cookiestore SHM used [%d] - Status", status); apr_table_set(r->notes, "CS_SHM" , "PROBLEM"); } } } /* Loop around clearance and save the cookies into the correct location_id */ return DECLINED; } } /* 6) If the Cookie does not have a special meaning to us, let's store them in the session store (without DLS) */ // store all other cookies to the cookiestore if (c->link_to_cookiestore == -1){ /* Here we have to update the c->link_to_cookiestore */ int cookiestore_offset = find_empty_cookiestore_slot(r); if (cookiestore_offset >= 0){ mod_but_cookie_cookiestore *cs; /* If we are here, we found an empty cookiestore shm storage we can put our stuff into */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: OUTPUT FILTER: ANCHOR LINK TO COOKIE STORE [%d]", cookiestore_offset); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Copy HEADER @ CS offset %d", cookiestore_offset); cs = apr_rmm_addr_get(cs_rmm_cookiestore, off_cookiestore[cookiestore_offset]); apr_cpystrn(cs->cookie_name, key1, sizeof(cs->cookie_name)); apr_cpystrn(cs->cookie_value, val1, sizeof(cs->cookie_value)); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STOREING NEW cookie_name [%s]=[%s] in CookieStore", cs->cookie_name, cs->cookie_value); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STOREING NEW cookie_name [%s] and cookie_value [%s] @ CS offset [%d] and cookie_next is [%d]", cs->cookie_name, cs->cookie_value, cookiestore_offset, cs->cookie_next); c->link_to_cookiestore = cookiestore_offset; cs->location_id = dconfig->mod_but_location_id; ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STOREING NEW cookie_name [%s] = [%s] ", cs->cookie_name, cs->cookie_value); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STOREING NEW cookie_name [%s] and cookie_value [%s] @ CS offset [%d] and cookie_next is [%d] and cookie_before is [%d]", cs->cookie_name, cs->cookie_value, cookiestore_offset, cs->cookie_next, cs->cookie_before); }else{ /* If we are here, we did not have more cookiestore shm */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unable finding new cookiestore slot"); apr_table_set(r->notes, "CS_SHM" , "PROBLEM"); } } else { int status; // if we are here, we are not the first cookie to be saved. ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STORE [%s]=[%s]", csp->cookie_name,csp->cookie_value); status = store_cookie_in_cookiestore(r, c->link_to_cookiestore, csp); if (status == 30){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: All Cookiestore SHM used [%d] - Status", status); apr_table_set(r->notes, "CS_SHM" , "PROBLEM"); } } } } ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; }
static apr_status_t test_rmm(apr_pool_t *parpool) { apr_status_t rv; apr_pool_t *pool; apr_shm_t *shm; apr_rmm_t *rmm; apr_size_t size, fragsize; apr_rmm_off_t *off; int i; void *entity; rv = apr_pool_create(&pool, parpool); if (rv != APR_SUCCESS) { fprintf(stderr, "Error creating child pool\n"); return rv; } /* We're going to want 10 blocks of data from our target rmm. */ size = SHARED_SIZE + apr_rmm_overhead_get(FRAG_COUNT + 1); printf("Creating anonymous shared memory (%" APR_SIZE_T_FMT " bytes).....", size); rv = apr_shm_create(&shm, size, NULL, pool); if (rv != APR_SUCCESS) { fprintf(stderr, "Error allocating shared memory block\n"); return rv; } fprintf(stdout, "OK\n"); printf("Creating rmm segment............................."); rv = apr_rmm_init(&rmm, NULL, apr_shm_baseaddr_get(shm), size, pool); if (rv != APR_SUCCESS) { fprintf(stderr, "Error allocating rmm..............\n"); return rv; } fprintf(stdout, "OK\n"); fragsize = SHARED_SIZE / FRAG_COUNT; printf("Creating each fragment of size %" APR_SIZE_T_FMT "................", fragsize); off = apr_palloc(pool, FRAG_COUNT * sizeof(apr_rmm_off_t)); for (i = 0; i < FRAG_COUNT; i++) { off[i] = apr_rmm_malloc(rmm, fragsize); } fprintf(stdout, "OK\n"); printf("Checking for out of memory allocation............"); if (apr_rmm_malloc(rmm, FRAG_SIZE * FRAG_COUNT) == 0) { fprintf(stdout, "OK\n"); } else { return APR_EGENERAL; } printf("Checking each fragment for address alignment....."); for (i = 0; i < FRAG_COUNT; i++) { char *c = apr_rmm_addr_get(rmm, off[i]); apr_size_t sc = (apr_size_t)c; if (off[i] == 0) { printf("allocation failed for offset %d\n", i); return APR_ENOMEM; } if (sc & 7) { printf("Bad alignment for fragment %d; %p not %p!\n", i, c, (void *)APR_ALIGN_DEFAULT((apr_size_t)c)); return APR_EGENERAL; } } fprintf(stdout, "OK\n"); printf("Setting each fragment to a unique value.........."); for (i = 0; i < FRAG_COUNT; i++) { int j; char **c = apr_rmm_addr_get(rmm, off[i]); for (j = 0; j < FRAG_SIZE; j++, c++) { *c = apr_itoa(pool, i + j); } } fprintf(stdout, "OK\n"); printf("Checking each fragment for its unique value......"); for (i = 0; i < FRAG_COUNT; i++) { int j; char **c = apr_rmm_addr_get(rmm, off[i]); for (j = 0; j < FRAG_SIZE; j++, c++) { char *d = apr_itoa(pool, i + j); if (strcmp(*c, d) != 0) { return APR_EGENERAL; } } } fprintf(stdout, "OK\n"); printf("Freeing each fragment............................"); for (i = 0; i < FRAG_COUNT; i++) { rv = apr_rmm_free(rmm, off[i]); if (rv != APR_SUCCESS) { return rv; } } fprintf(stdout, "OK\n"); printf("Creating one large segment......................."); off[0] = apr_rmm_calloc(rmm, SHARED_SIZE); fprintf(stdout, "OK\n"); printf("Setting large segment............................"); for (i = 0; i < FRAG_COUNT * FRAG_SIZE; i++) { char **c = apr_rmm_addr_get(rmm, off[0]); c[i] = apr_itoa(pool, i); } fprintf(stdout, "OK\n"); printf("Freeing large segment............................"); apr_rmm_free(rmm, off[0]); fprintf(stdout, "OK\n"); printf("Creating each fragment of size %" APR_SIZE_T_FMT " (again)........", fragsize); for (i = 0; i < FRAG_COUNT; i++) { off[i] = apr_rmm_malloc(rmm, fragsize); } fprintf(stdout, "OK\n"); printf("Freeing each fragment backwards.................."); for (i = FRAG_COUNT - 1; i >= 0; i--) { rv = apr_rmm_free(rmm, off[i]); if (rv != APR_SUCCESS) { return rv; } } fprintf(stdout, "OK\n"); printf("Creating one large segment (again)..............."); off[0] = apr_rmm_calloc(rmm, SHARED_SIZE); fprintf(stdout, "OK\n"); printf("Freeing large segment............................"); apr_rmm_free(rmm, off[0]); fprintf(stdout, "OK\n"); printf("Checking realloc................................."); off[0] = apr_rmm_calloc(rmm, SHARED_SIZE - 100); off[1] = apr_rmm_calloc(rmm, 100); if (off[0] == 0 || off[1] == 0) { printf("FAILED\n"); return APR_EINVAL; } entity = apr_rmm_addr_get(rmm, off[1]); rv = apr_rmm_free(rmm, off[0]); if (rv != APR_SUCCESS) { printf("FAILED\n"); return rv; } { unsigned char *c = entity; /* Fill in the region; the first half with zereos, which will * likely catch the apr_rmm_realloc offset calculation bug by * making it think the old region was zero length. */ for (i = 0; i < 100; i++) { c[i] = (i < 50) ? 0 : i; } } /* now we can realloc off[1] and get many more bytes */ off[0] = apr_rmm_realloc(rmm, entity, SHARED_SIZE - 100); if (off[0] == 0) { printf("FAILED\n"); return APR_EINVAL; } { unsigned char *c = apr_rmm_addr_get(rmm, off[0]); /* fill in the region */ for (i = 0; i < 100; i++) { if (c[i] != (i < 50 ? 0 : i)) { printf("FAILED at offset %d: %hx\n", i, c[i]); return APR_EGENERAL; } } } fprintf(stdout, "OK\n"); printf("Destroying rmm segment..........................."); rv = apr_rmm_destroy(rmm); if (rv != APR_SUCCESS) { printf("FAILED\n"); return rv; } printf("OK\n"); printf("Destroying shared memory segment................."); rv = apr_shm_destroy(shm); if (rv != APR_SUCCESS) { printf("FAILED\n"); return rv; } printf("OK\n"); apr_pool_destroy(pool); return APR_SUCCESS; }
static void test_rmm(abts_case *tc, void *data) { apr_status_t rv; apr_pool_t *pool; apr_shm_t *shm; apr_rmm_t *rmm; apr_size_t size, fragsize; apr_rmm_off_t *off, off2; int i; void *entity; rv = apr_pool_create(&pool, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* We're going to want 10 blocks of data from our target rmm. */ size = SHARED_SIZE + apr_rmm_overhead_get(FRAG_COUNT + 1); rv = apr_shm_create(&shm, size, NULL, pool); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); if (rv != APR_SUCCESS) return; rv = apr_rmm_init(&rmm, NULL, apr_shm_baseaddr_get(shm), size, pool); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); if (rv != APR_SUCCESS) return; /* Creating each fragment of size fragsize */ fragsize = SHARED_SIZE / FRAG_COUNT; off = apr_palloc(pool, FRAG_COUNT * sizeof(apr_rmm_off_t)); for (i = 0; i < FRAG_COUNT; i++) { off[i] = apr_rmm_malloc(rmm, fragsize); } /* Checking for out of memory allocation */ off2 = apr_rmm_malloc(rmm, FRAG_SIZE * FRAG_COUNT); ABTS_TRUE(tc, !off2); /* Checking each fragment for address alignment */ for (i = 0; i < FRAG_COUNT; i++) { char *c = apr_rmm_addr_get(rmm, off[i]); apr_size_t sc = (apr_size_t)c; ABTS_TRUE(tc, !!off[i]); ABTS_TRUE(tc, !(sc & 7)); } /* Setting each fragment to a unique value */ for (i = 0; i < FRAG_COUNT; i++) { int j; char **c = apr_rmm_addr_get(rmm, off[i]); for (j = 0; j < FRAG_SIZE; j++, c++) { *c = apr_itoa(pool, i + j); } } /* Checking each fragment for its unique value */ for (i = 0; i < FRAG_COUNT; i++) { int j; char **c = apr_rmm_addr_get(rmm, off[i]); for (j = 0; j < FRAG_SIZE; j++, c++) { char *d = apr_itoa(pool, i + j); ABTS_STR_EQUAL(tc, d, *c); } } /* Freeing each fragment */ for (i = 0; i < FRAG_COUNT; i++) { rv = apr_rmm_free(rmm, off[i]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } /* Creating one large segment */ off[0] = apr_rmm_calloc(rmm, SHARED_SIZE); /* Setting large segment */ for (i = 0; i < FRAG_COUNT * FRAG_SIZE; i++) { char **c = apr_rmm_addr_get(rmm, off[0]); c[i] = apr_itoa(pool, i); } /* Freeing large segment */ rv = apr_rmm_free(rmm, off[0]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* Creating each fragment of size fragsize */ for (i = 0; i < FRAG_COUNT; i++) { off[i] = apr_rmm_malloc(rmm, fragsize); } /* Freeing each fragment backwards */ for (i = FRAG_COUNT - 1; i >= 0; i--) { rv = apr_rmm_free(rmm, off[i]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } /* Creating one large segment (again) */ off[0] = apr_rmm_calloc(rmm, SHARED_SIZE); /* Freeing large segment */ rv = apr_rmm_free(rmm, off[0]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* Checking realloc */ off[0] = apr_rmm_calloc(rmm, SHARED_SIZE - 100); off[1] = apr_rmm_calloc(rmm, 100); ABTS_TRUE(tc, !!off[0]); ABTS_TRUE(tc, !!off[1]); entity = apr_rmm_addr_get(rmm, off[1]); rv = apr_rmm_free(rmm, off[0]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); { unsigned char *c = entity; /* Fill in the region; the first half with zereos, which will * likely catch the apr_rmm_realloc offset calculation bug by * making it think the old region was zero length. */ for (i = 0; i < 100; i++) { c[i] = (i < 50) ? 0 : i; } } /* now we can realloc off[1] and get many more bytes */ off[0] = apr_rmm_realloc(rmm, entity, SHARED_SIZE - 100); ABTS_TRUE(tc, !!off[0]); { unsigned char *c = apr_rmm_addr_get(rmm, off[0]); /* fill in the region */ for (i = 0; i < 100; i++) { ABTS_TRUE(tc, c[i] == (i < 50 ? 0 : i)); } } rv = apr_rmm_destroy(rmm); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_shm_destroy(shm); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); apr_pool_destroy(pool); }
char *fetch_key(ServerConfig *config, char *key) { return (char *)apr_rmm_addr_get(config->cache_rmm, apr_rmm_offset_get(config->cache_rmm, key)); }