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);
				}
			}
		}
	}
}
Example #3
0
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;
			}
		}
	}
}
Example #10
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;
}
Example #16
0
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;
}
Example #17
0
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));
}