Ejemplo n.º 1
0
/**
 * Look at the request to see if Caucho should handle it.
 */
static int
cse_dispatch(request_rec *r)
{
  config_t *config = cse_get_module_config(r);
  const char *host = ap_get_server_name(r);
  const char *uri = r->uri;
  unsigned int now = r->request_time;

  LOG(("CONF: %p\n", config));
  
  if (config == NULL)
    return DECLINED;

  /*
  cse_update_config(config, r->request_time);
  */
  
  if (config->enable_caucho_status && strstr(uri, "/caucho-status")) {
    r->handler = "caucho-status";
    return OK;
  }

  /* Check for exact virtual host match */
  if (cse_match_request(config, host, ap_get_server_port(r), uri, 0, now) ||
      r->handler && ! strcmp(r->handler, "caucho-request")) {
    r->handler = "caucho-request";
    
    LOG(("[%d] match %s:%s\n", getpid(), host ? host : "null", uri));
    return OK;
  }

  LOG(("[%d] mismatch %s:%s\n", getpid(), host ? host : "null", uri));

  return DECLINED;
}
Ejemplo n.º 2
0
// Get the full URI of the request_rec's request location 
// clean_params specifies whether or not all openid.* and modauthopenid.* params should be cleared
static void full_uri(request_rec *r, std::string& result, modauthopenid_config *s_cfg, bool clean_params=false) {
  std::string hostname(r->hostname);
  std::string uri(r->uri);
  apr_port_t i_port = ap_get_server_port(r);
  // Fetch the APR function for determining if we are looking at an https URL
  APR_OPTIONAL_FN_TYPE(ssl_is_https) *using_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
  std::string prefix = (using_https != NULL && using_https(r->connection)) ? "https://" : "http://";
  char *port = apr_psprintf(r->pool, "%lu", (unsigned long) i_port);
  std::string s_port = (i_port == 80 || i_port == 443) ? "" : ":" + std::string(port);

  std::string args;
  if(clean_params) {
    opkele::params_t params;
    if(r->args != NULL) params = modauthopenid::parse_query_string(std::string(r->args));
    modauthopenid::remove_openid_vars(params);
    args = params.append_query("", "");
  } else {
    args = (r->args == NULL) ? "" : "?" + std::string(r->args);
  }

  if(s_cfg->server_name == NULL)
    result = prefix + hostname + s_port + uri + args;
  else
    result = std::string(s_cfg->server_name) + uri + args;
}
Ejemplo n.º 3
0
CAMLprim value
netcgi2_apache_request_port(value rv)
{
    CAMLparam1(rv);
    request_rec *r = Request_rec_val (rv);

    CAMLreturn(Val_int(ap_get_server_port(r)));
}
Ejemplo n.º 4
0
/**
 * Look at the request to see if Resin should handle it.
 */
static int
cse_dispatch(request_rec *r)
{
  config_t *config = cse_get_module_config(r);
  const char *host_name = ap_get_server_name(r);
  int port = ap_get_server_port(r);
  const char *uri = r->uri;
  resin_host_t *host;
  unsigned int now;
  int len;

  if (config == NULL || ! uri)
    return DECLINED;

  now = time(0);
 
  LOG(("%s:%d:cse_dispatch(): [%d] host %s\n",
       __FILE__, __LINE__, getpid(), host_name ? host_name : "null"));

  len = strlen(uri);

  /* move back below host */
  if (config->enable_caucho_status &&
      len >= sizeof("/caucho-status") - 1 &&
      ! strcmp(uri + len - sizeof("/caucho-status") + 1, "/caucho-status")) {
    r->handler = "caucho-status";
    return caucho_status(r);
  }
  
  /* Check for exact virtual host match */
  host = cse_match_request(config, host_name, port, uri, 0, now);
  
  if (host || (r->handler && ! strcmp(r->handler, "caucho-request"))) {
    LOG(("%s:%d:cse_dispatch(): [%d] match %s:%s\n",
	 __FILE__, __LINE__, getpid(), host_name ? host_name : "null", uri));

    return caucho_request(r, config, host, now);
  }
  else if (r->handler && ! strcmp(r->handler, "caucho-status")) {
    return caucho_status(r);
  }
  
  if (config->session_url_prefix) {
    return cse_strip(r);
  }

  return DECLINED;
}
Ejemplo n.º 5
0
static int
check_request_acl(request_rec *r, int req_access) {
    char *dir_path, *acl_path;
    apr_finfo_t acl_finfo;

    const char *req_uri, *dir_uri, *acl_uri, *access;
    const char *port, *par_uri, *req_file;

    librdf_world *rdf_world = NULL;
    librdf_storage *rdf_storage = NULL;
    librdf_model *rdf_model = NULL;
    librdf_parser *rdf_parser = NULL;
    librdf_uri *rdf_uri_acl = NULL,
               *rdf_uri_base = NULL;

    int ret = HTTP_FORBIDDEN;

    // dir_path: parent directory of request filename
    // acl_path: absolute path to request ACL
    dir_path = ap_make_dirstr_parent(r->pool, r->filename);
    acl_path = ap_make_full_path(r->pool, dir_path, WEBID_ACL_FNAME);

    if (apr_filepath_merge(&acl_path, NULL, acl_path, APR_FILEPATH_NOTRELATIVE, r->pool) != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                      "Module bug?  Request filename path %s is invalid or "
                      "or not absolute for uri %s",
                      r->filename, r->uri);
        return HTTP_FORBIDDEN;
    }

    // acl_path: 403 if missing
    if ((apr_stat(&acl_finfo, acl_path, APR_FINFO_TYPE, r->pool) != APR_SUCCESS) ||
        (acl_finfo.filetype != APR_REG)) {
        return HTTP_FORBIDDEN;
    }

    // req_uri: fully qualified URI of request filename
    // dir_uri: fully qualified URI of request filename parent
    // acl_uri: fully qualified URI of request filename ACL
    // access: ACL URI of requested access
    port = ap_is_default_port(ap_get_server_port(r), r)
           ? "" : apr_psprintf(r->pool, ":%u", ap_get_server_port(r));
    req_uri = apr_psprintf(r->pool, "%s://%s%s%s%s",
                           ap_http_scheme(r), ap_get_server_name(r), port,
                           (*r->uri == '/') ? "" : "/",
                           r->uri);
    par_uri = ap_make_dirstr_parent(r->pool, r->uri);
    dir_uri = apr_psprintf(r->pool, "%s://%s%s%s%s",
                           ap_http_scheme(r), ap_get_server_name(r), port,
                           (*par_uri == '/') ? "" : "/",
                           par_uri);
    acl_uri = ap_make_full_path(r->pool, dir_uri, WEBID_ACL_FNAME);

    if (req_access == WEBID_ACCESS_READ) {
        access = "Read";
    } else if (req_access == WEBID_ACCESS_WRITE) {
        if ((req_file = strrchr(r->filename, '/')) != NULL &&
            strcmp(++req_file, WEBID_ACL_FNAME) == 0)
            access = "Control";
        else
            access = "Write";
    } else {
        access = "Control";
    }

    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
                  "[ACL] %s (%s) %s | URI: %s | DIR: %s (%s) | ACL: %s (%s) | status: %d",
                  r->method, access, r->uri, req_uri, dir_uri, dir_path, acl_uri, acl_path, r->status);

    if ((rdf_world = librdf_new_world()) != NULL) {
        librdf_world_open(rdf_world);
        if ((rdf_storage = librdf_new_storage(rdf_world, "memory", NULL, NULL)) != NULL) {
            if ((rdf_model = librdf_new_model(rdf_world, rdf_storage, NULL)) != NULL) {
                if ((rdf_parser = librdf_new_parser(rdf_world, "turtle", NULL, NULL)) != NULL) {
                    if ((rdf_uri_base = librdf_new_uri(rdf_world, (unsigned char*)acl_uri)) != NULL) {
                        if ((rdf_uri_acl = librdf_new_uri_from_filename(rdf_world, acl_path)) != NULL) {
                            if (!librdf_parser_parse_into_model(rdf_parser, rdf_uri_acl, rdf_uri_base, rdf_model)) {
                                //log_stream_prefix(r, librdf_model_as_stream(rdf_model), "[ACL] [model]");
                                if (query_results(r, rdf_world, rdf_model,
                                    apr_psprintf(r->pool, SPARQL_URI_MODE_AGENT, "accessTo", req_uri, access, r->user)) > 0 || \
                                    query_results(r, rdf_world, rdf_model,
                                    apr_psprintf(r->pool, SPARQL_URI_MODE_AGENTCLASS, "accessTo", req_uri, access, r->user)) > 0 || \
                                    query_results(r, rdf_world, rdf_model,
                                    apr_psprintf(r->pool, SPARQL_URI_MODE_WORLD, "accessTo", req_uri, access)) > 0 || \
                                    ( ( query_results(r, rdf_world, rdf_model,
                                        apr_psprintf(r->pool, SPARQL_URI_ACL_EXISTS, "accessTo", req_uri )) == 0 ) &&
                                      ( query_results(r, rdf_world, rdf_model,
                                        apr_psprintf(r->pool, SPARQL_URI_MODE_AGENT, "defaultForNew", dir_uri, access, r->user)) > 0 || \
                                        query_results(r, rdf_world, rdf_model,
                                        apr_psprintf(r->pool, SPARQL_URI_MODE_AGENTCLASS, "defaultForNew", dir_uri, access, r->user)) > 0 || \
                                        query_results(r, rdf_world, rdf_model,
                                        apr_psprintf(r->pool, SPARQL_URI_MODE_WORLD, "defaultForNew", dir_uri, access)) > 0 ) ) ) {
                                    apr_table_set(r->headers_out, "Link", apr_psprintf(r->pool, "%s; rel=meta", acl_uri));
                                    ret = OK;
                                }
                            } else
                                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_parser_parse_into_model failed");
                            librdf_free_uri(rdf_uri_acl);
                        } else
                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_uri_from_filename returned NULL");
                        librdf_free_uri(rdf_uri_base);
                    } else
                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_uri returned NULL");
                    librdf_free_parser(rdf_parser);
                } else
                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_parser returned NULL");
                librdf_free_model(rdf_model);
            } else
                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_model returned NULL");
            librdf_free_storage(rdf_storage);
        } else
            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_storage returned NULL");
        librdf_free_world(rdf_world);
    } else
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "librdf_new_world returned NULL");

    return ret;
}
Ejemplo n.º 6
0
/*
	This function parses the http-response headers from a backend system. 
	We want to find out if the response-header has a
	a) Set-Cookie header which should be stored to the session store
	b) Set-Cookie header which is configured as "free" cookie
	c) Set-Cookie header which has a special meaning to us (Auth=ok)
*/
static apr_status_t mod_but_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in)
{
	apr_int64_t i;
	int shmoffsetnew;
	char *pshm_offset_number;

	apr_port_t port = 0;
	char *host = NULL;
	char *all_shm_space_used_url = NULL;
	const char *protocol, *ssl_session_id, *ssl_cipher;

	request_rec *r = f->r;
	mod_but_server_t *config = ap_get_module_config(r->server->module_config, &but_module);

	cookie_res *cr = apr_palloc(r->pool, sizeof(cookie_res));
        cr->r = r;
        cr->cookie = NULL;

	apr_int64_t num_set_cookie;

	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);



	/*
		This checks if the response has a Set-Cookie set. There could be

			a) NO Set-Cookie in response-header
			b) LOGON Set-Cookie in response-header
			c) FREE COOKIE in response-header
			d) Other's Cookies in response-header (belonging into session store)

	*/
	

	ap_log_rerror(PC_LOG_INFO, r, "mod_but: Calling apr_table_do(mod_but_analyze_response_headers)");

	


	/*
		Do Header Parsing for all Response Headers. We are looking for

		a) MOD_BUT SESSION
		b) FREE COOKIES
		c) SERVICE_LIST COOKIES
		d) OTHER COOKIES	
	*/	
	apr_table_set(r->notes, "NUM_SET_COOKIE", "0");
	apr_table_do(mod_but_analyze_response_headers, cr, r->headers_out, NULL);
	ap_log_rerror(PC_LOG_CRIT, r, "mod_but: FINISHED MOD_BUT_ANALYZE_RESPONSE_HEADER");


	/*
		Unsetting all Set-Cookie Headers from Response (All but MOD_BUT_SESSION)
	*/
	apr_table_unset(r->headers_out, "Set-Cookie");
	apr_table_unset(r->err_headers_out, "Set-Cookie");
	ap_log_rerror(PC_LOG_CRIT, r, "mod_but: P1: UNSETTING ALL RESPONSE HEADERS");

	/*
		Setting FREE Cookies into the Response Header manually
	*/
	num_set_cookie = apr_atoi64(apr_table_get(r->notes, "NUM_SET_COOKIE"));
	for (i = 1; i <= num_set_cookie; i++) {
		ap_log_rerror(PC_LOG_INFO, r, "mod_but: FOR LOOP -- NUM_SET_COOKIE IS [%s]", apr_table_get(r->notes, "NUM_SET_COOKIE"));
		ap_log_rerror(PC_LOG_INFO, r, "mod_but: VALUE IS [%s]", apr_table_get(r->notes, apr_itoa(r->pool, i)));
		apr_table_set(r->headers_out, "Set-Cookie", apr_table_get(r->notes, apr_itoa(r->pool, i)));
		ap_log_rerror(PC_LOG_CRIT, r, "mod_but: P2: SETTING FREE COOKIES INTO THE RESPONSE");
	}


	/*
		If apr_table_do detected a LOGON=ok Set-Cookie Header, There will be a r->notes about it. Otherwise
		r->notes is empty.
	*/
	if (apr_table_get(r->notes, "LOGON_STATUS") != NULL) {
		ap_log_rerror(PC_LOG_INFO, r, "mod_but: LOGON STATUS = [%s]", apr_table_get(r->notes, "LOGON_STATUS"));
		i = apr_atoi64(apr_table_get(r->notes, "SHMOFFSET"));
		ap_log_rerror(PC_LOG_INFO, r, "mod_but: VOR renew_mod_but_session in mod_but.c");
		shmoffsetnew = renew_mod_but_session(i, r);

		if (shmoffsetnew == -1)
		{
			ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with SHM Creation, DECLINED");
			apr_table_unset(r->headers_out, "Set-Cookie");
			apr_table_unset(r->err_headers_out, "Set-Cookie");

			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");
			r->content_type = NULL;
			return OK;
		}

		if (shmoffsetnew == -2)
		{
			ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with SID Creation, DECLINED");
			ap_log_rerror(PC_LOG_INFO, r, "mod_but: END OF OUTPUT FILTER");
			//return 2400;
			return OK;
		}

		ap_log_rerror(PC_LOG_INFO, r, "mod_but: OUTPUT FILTER: SHMOFFSET BEFORE [%s]", apr_table_get(r->notes, "SHMOFFSET"));

		/*
			This is the runtime fix, so that the other stuff will have the correct SHMOFFSET.
			renew_mod_but_session returned the new SHMOFFST we have to put into r->notes
		*/
		pshm_offset_number = apr_itoa(r->pool, shmoffsetnew);
		apr_table_set(r->notes, "SHMOFFSET", pshm_offset_number);
		ap_log_rerror(PC_LOG_INFO, r, "mod_but: END OF OUTPUT FILTER");
	}

	if (apr_table_get(r->notes, "CS_SHM") != NULL) {
		ap_log_rerror(PC_LOG_INFO, r, "mod_but: Problems with SHM Cookie Store - ALERT - No space left in SHM Cookiestore to include a processing header");
	}

	ap_log_rerror(PC_LOG_CRIT, r, "mod_but: P3: BEFORE REMOVE OUTPUT FILTER");
        ap_remove_output_filter(f);
	ap_log_rerror(PC_LOG_CRIT, r, "mod_but: P4: AFTER REMOVE OUTPUT FILTER & BEFORE AP_PASS_BRIGADE");
        return ap_pass_brigade(f->next, bb_in);
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
static void vhost_alias_interpolate(request_rec *r, mva_sconf_t *conf,
				    const char *name, const char *map,
				    const char *uri)
{
    /* 0..9 9..0 */
    enum { MAXDOTS = 19 };
    const char *dots[MAXDOTS+1];
    int ndots;

    char buf[HUGE_STRING_LEN];
    char *dest;
    const char *docroot;

    int N, M, Np, Mp, Nd, Md;
    const char *start, *end;

    const char *p;

    ndots = 0;
    dots[ndots++] = name-1; /* slightly naughty */
    for (p = name; *p; ++p){
        if (*p == '.' && ndots < MAXDOTS) {
            dots[ndots++] = p;
        }
    }
    dots[ndots] = p;

    r->filename = NULL;

    dest = buf;
    while (*map) {
        if (*map != '%') {
            /* normal characters */
            vhost_alias_checkspace(r, buf, &dest, 1);
            *dest++ = *map++;
            continue;
        }
        /* we are in a format specifier */
        ++map;
        /* %% -> % */
        if (*map == '%') {
            ++map;
            vhost_alias_checkspace(r, buf, &dest, 1);
            *dest++ = '%';
            continue;
        }
        /* port number */
        if (*map == 'p') {
            ++map;
            /* no. of decimal digits in a short plus one */
            vhost_alias_checkspace(r, buf, &dest, 7);
            dest += apr_snprintf(dest, 7, "%d", ap_get_server_port(r));
            continue;
        }
        /* deal with %-N+.-M+ -- syntax is already checked */
        M = 0;   /* value */
        Np = Mp = 0; /* is there a plus? */
        Nd = Md = 0; /* is there a dash? */
        if (*map == '-') ++map, Nd = 1;
        N = *map++ - '0';
        if (*map == '+') ++map, Np = 1;
        if (*map == '.') {
            ++map;
            if (*map == '-') {
                ++map, Md = 1;
            }
            M = *map++ - '0';
            if (*map == '+') {
                ++map, Mp = 1;
            }
        }
        /* note that N and M are one-based indices, not zero-based */
        start = dots[0]+1; /* ptr to the first character */
        end = dots[ndots]; /* ptr to the character after the last one */
        if (N != 0) {
            if (N > ndots) {
                start = "_";
                end = start+1;
            }
            else if (!Nd) {
                start = dots[N-1]+1;
                if (!Np) {
                    end = dots[N];
                }
            }
            else {
                if (!Np) {
                    start = dots[ndots-N]+1;
                }
                end = dots[ndots-N+1];
            }
        }
        if (M != 0) {
            if (M > end - start) {
                start = "_";
                end = start+1;
            }
            else if (!Md) {
                start = start+M-1;
                if (!Mp) {
                    end = start+1;
                }
            }
            else {
                if (!Mp) {
                    start = end-M;
                }
                end = end-M+1;
            }
        }
        vhost_alias_checkspace(r, buf, &dest, end - start);
        for (p = start; p < end; ++p) {
            *dest++ = apr_tolower(*p);
        }
    }
    /* no double slashes */
    if (dest - buf > 0 && dest[-1] == '/') {
        --dest;
    }
    *dest = '\0';
    
    /*
     * A this point we either have a document root which points to something
     * on disk - or not.
     *
     * If the document root doesn't exist on disk we can *attempt* to remap
     * that to the real file.
     *
     * If this remapping fails we don't care as the result will be a 404,
     * and that would have happened anyway.
     *
     */
    {
      struct stat buffer;

      /**
       * If we have:
       *
       *  A document root
       *  Which doesn't exist.
       *
       * Then:
       *
       *  Attempt to fix.
       *
       */
      if ( ( NULL != buf ) &&
           ( stat( buf, &buffer ) < 0 ) )
        {

          /**
           * Here we strip out the first part of the name
           * after the /srv prefix which will result in
           * a request being rewritten from (for example)
           *
           *   /srv/test.example.com/public/htdocs
           *
           * to:
           *
           *   /srv/example.com/public/htdocs
           *
           */
          update_vhost_request( buf );
        }
    }
    
    if (r->filename)
        docroot = apr_pstrcat(r->pool, r->filename, buf, NULL);
    else
        docroot = apr_pstrdup(r->pool, buf);
    r->filename = apr_pstrcat(r->pool, docroot, uri, NULL);


    ap_set_context_info(r, NULL, docroot);
    ap_set_document_root(r, docroot);
}
static apr_status_t cache_canonicalise_key(request_rec *r, apr_pool_t* p,
        const char *uri, apr_uri_t *parsed_uri, const char **key)
{
    cache_server_conf *conf;
    char *port_str, *hn, *lcs;
    const char *hostname, *scheme;
    int i;
    const char *path;
    char *querystring;

    if (*key) {
        /*
         * We have been here before during the processing of this request.
         */
        return APR_SUCCESS;
    }

    /*
     * Get the module configuration. We need this for the CacheIgnoreQueryString
     * option below.
     */
    conf = (cache_server_conf *) ap_get_module_config(r->server->module_config,
            &cache_module);

    /*
     * Use the canonical name to improve cache hit rate, but only if this is
     * not a proxy request or if this is a reverse proxy request.
     * We need to handle both cases in the same manner as for the reverse proxy
     * case we have the following situation:
     *
     * If a cached entry is looked up by mod_cache's quick handler r->proxyreq
     * is still unset in the reverse proxy case as it only gets set in the
     * translate name hook (either by ProxyPass or mod_rewrite) which is run
     * after the quick handler hook. This is different to the forward proxy
     * case where it gets set before the quick handler is run (in the
     * post_read_request hook).
     * If a cache entry is created by the CACHE_SAVE filter we always have
     * r->proxyreq set correctly.
     * So we must ensure that in the reverse proxy case we use the same code
     * path and using the canonical name seems to be the right thing to do
     * in the reverse proxy case.
     */
    if (!r->proxyreq || (r->proxyreq == PROXYREQ_REVERSE)) {
        if (conf->base_uri && conf->base_uri->hostname) {
            hostname = conf->base_uri->hostname;
        }
        else {
            /* Use _default_ as the hostname if none present, as in mod_vhost */
            hostname = ap_get_server_name(r);
            if (!hostname) {
                hostname = "_default_";
            }
        }
    }
    else if (parsed_uri->hostname) {
        /* Copy the parsed uri hostname */
        hn = apr_pstrdup(p, parsed_uri->hostname);
        ap_str_tolower(hn);
        /* const work-around */
        hostname = hn;
    }
    else {
        /* We are a proxied request, with no hostname. Unlikely
         * to get very far - but just in case */
        hostname = "_default_";
    }

    /*
     * Copy the scheme, ensuring that it is lower case. If the parsed uri
     * contains no string or if this is not a proxy request get the http
     * scheme for this request. As r->parsed_uri.scheme is not set if this
     * is a reverse proxy request, it is ensured that the cases
     * "no proxy request" and "reverse proxy request" are handled in the same
     * manner (see above why this is needed).
     */
    if (r->proxyreq && parsed_uri->scheme) {
        /* Copy the scheme and lower-case it */
        lcs = apr_pstrdup(p, parsed_uri->scheme);
        ap_str_tolower(lcs);
        /* const work-around */
        scheme = lcs;
    }
    else {
        if (conf->base_uri && conf->base_uri->scheme) {
            scheme = conf->base_uri->scheme;
        }
        else {
            scheme = ap_http_scheme(r);
        }
    }

    /*
     * If this is a proxy request, but not a reverse proxy request (see comment
     * above why these cases must be handled in the same manner), copy the
     * URI's port-string (which may be a service name). If the URI contains
     * no port-string, use apr-util's notion of the default port for that
     * scheme - if available. Otherwise use the port-number of the current
     * server.
     */
    if (r->proxyreq && (r->proxyreq != PROXYREQ_REVERSE)) {
        if (parsed_uri->port_str) {
            port_str = apr_pcalloc(p, strlen(parsed_uri->port_str) + 2);
            port_str[0] = ':';
            for (i = 0; parsed_uri->port_str[i]; i++) {
                port_str[i + 1] = apr_tolower(parsed_uri->port_str[i]);
            }
        }
        else if (apr_uri_port_of_scheme(scheme)) {
            port_str = apr_psprintf(p, ":%u", apr_uri_port_of_scheme(scheme));
        }
        else {
            /* No port string given in the AbsoluteUri, and we have no
             * idea what the default port for the scheme is. Leave it
             * blank and live with the inefficiency of some extra cached
             * entities.
             */
            port_str = "";
        }
    }
    else {
        if (conf->base_uri && conf->base_uri->port_str) {
            port_str = conf->base_uri->port_str;
        }
        else if (conf->base_uri && conf->base_uri->hostname) {
            port_str = "";
        }
        else {
            /* Use the server port */
            port_str = apr_psprintf(p, ":%u", ap_get_server_port(r));
        }
    }

    /*
     * Check if we need to ignore session identifiers in the URL and do so
     * if needed.
     */
    path = uri;
    querystring = parsed_uri->query;
    if (conf->ignore_session_id->nelts) {
        int i;
        char **identifier;

        identifier = (char **) conf->ignore_session_id->elts;
        for (i = 0; i < conf->ignore_session_id->nelts; i++, identifier++) {
            int len;
            const char *param;

            len = strlen(*identifier);
            /*
             * Check that we have a parameter separator in the last segment
             * of the path and that the parameter matches our identifier
             */
            if ((param = ap_strrchr_c(path, ';'))
                    && !strncmp(param + 1, *identifier, len)
                    && (*(param + len + 1) == '=')
                    && !ap_strchr_c(param + len + 2, '/')) {
                path = apr_pstrndup(p, path, param - path);
                continue;
            }
            /*
             * Check if the identifier is in the querystring and cut it out.
             */
            if (querystring) {
                /*
                 * First check if the identifier is at the beginning of the
                 * querystring and followed by a '='
                 */
                if (!strncmp(querystring, *identifier, len)
                        && (*(querystring + len) == '=')) {
                    param = querystring;
                }
                else {
                    char *complete;

                    /*
                     * In order to avoid subkey matching (PR 48401) prepend
                     * identifier with a '&' and append a '='
                     */
                    complete = apr_pstrcat(p, "&", *identifier, "=", NULL);
                    param = strstr(querystring, complete);
                    /* If we found something we are sitting on the '&' */
                    if (param) {
                        param++;
                    }
                }
                if (param) {
                    const char *amp;

                    if (querystring != param) {
                        querystring = apr_pstrndup(p, querystring,
                                param - querystring);
                    }
                    else {
                        querystring = "";
                    }

                    if ((amp = ap_strchr_c(param + len + 1, '&'))) {
                        querystring = apr_pstrcat(p, querystring, amp + 1,
                                NULL);
                    }
                    else {
                        /*
                         * If querystring is not "", then we have the case
                         * that the identifier parameter we removed was the
                         * last one in the original querystring. Hence we have
                         * a trailing '&' which needs to be removed.
                         */
                        if (*querystring) {
                            querystring[strlen(querystring) - 1] = '\0';
                        }
                    }
                }
            }
        }
    }

    /* Key format is a URI, optionally without the query-string */
    if (conf->ignorequerystring) {
        *key = apr_pstrcat(p, scheme, "://", hostname, port_str, path, "?",
                NULL);
    }
    else {
        *key = apr_pstrcat(p, scheme, "://", hostname, port_str, path, "?",
                querystring, NULL);
    }

    /*
     * Store the key in the request_config for the cache as r->parsed_uri
     * might have changed in the time from our first visit here triggered by the
     * quick handler and our possible second visit triggered by the CACHE_SAVE
     * filter (e.g. r->parsed_uri got unescaped). In this case we would save the
     * resource in the cache under a key where it is never found by the quick
     * handler during following requests.
     */
    ap_log_rerror(
            APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, r, APLOGNO(00698) "cache: Key for entity %s?%s is %s", uri, parsed_uri->query, *key);

    return APR_SUCCESS;
}
Ejemplo n.º 10
0
AP_DECLARE(void) ap_add_common_vars(request_rec *r)
{
    apr_table_t *e;
    server_rec *s = r->server;
    conn_rec *c = r->connection;
    core_dir_config *conf =
        (core_dir_config *)ap_get_core_module_config(r->per_dir_config);
    const char *env_temp;
    const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in);
    const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts;
    int i;
    apr_port_t rport;
    char *q;

    /* use a temporary apr_table_t which we'll overlap onto
     * r->subprocess_env later
     * (exception: if r->subprocess_env is empty at the start,
     * write directly into it)
     */
    if (apr_is_empty_table(r->subprocess_env)) {
        e = r->subprocess_env;
    }
    else {
        e = apr_table_make(r->pool, 25 + hdrs_arr->nelts);
    }

    /* First, add environment vars from headers... this is as per
     * CGI specs, though other sorts of scripting interfaces see
     * the same vars...
     */

    for (i = 0; i < hdrs_arr->nelts; ++i) {
        if (!hdrs[i].key) {
            continue;
        }

        /* A few headers are special cased --- Authorization to prevent
         * rogue scripts from capturing passwords; content-type and -length
         * for no particular reason.
         */

        if (!strcasecmp(hdrs[i].key, "Content-type")) {
            apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
        }
        else if (!strcasecmp(hdrs[i].key, "Content-length")) {
            apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
        }
        /*
         * You really don't want to disable this check, since it leaves you
         * wide open to CGIs stealing passwords and people viewing them
         * in the environment with "ps -e".  But, if you must...
         */
#ifndef SECURITY_HOLE_PASS_AUTHORIZATION
        else if (!strcasecmp(hdrs[i].key, "Authorization")
                 || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) {
            if (conf->cgi_pass_auth == AP_CGI_PASS_AUTH_ON) {
                add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
            }
        }
#endif
        else
            add_unless_null(e, http2env(r, hdrs[i].key), hdrs[i].val);
    }

    env_temp = apr_table_get(r->subprocess_env, "PATH");
    if (env_temp == NULL) {
        env_temp = getenv("PATH");
    }
    if (env_temp == NULL) {
        env_temp = DEFAULT_PATH;
    }
    apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_temp));

#if defined(WIN32)
    env2env(e, "SystemRoot");
    env2env(e, "COMSPEC");
    env2env(e, "PATHEXT");
    env2env(e, "WINDIR");
#elif defined(OS2)
    env2env(e, "COMSPEC");
    env2env(e, "ETC");
    env2env(e, "DPATH");
    env2env(e, "PERLLIB_PREFIX");
#elif defined(BEOS)
    env2env(e, "LIBRARY_PATH");
#elif defined(DARWIN)
    env2env(e, "DYLD_LIBRARY_PATH");
#elif defined(_AIX)
    env2env(e, "LIBPATH");
#elif defined(__HPUX__)
    /* HPUX PARISC 2.0W knows both, otherwise redundancy is harmless */
    env2env(e, "SHLIB_PATH");
    env2env(e, "LD_LIBRARY_PATH");
#else /* Some Unix */
    env2env(e, "LD_LIBRARY_PATH");
#endif

    apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
    apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_banner());
    apr_table_addn(e, "SERVER_NAME",
                   ap_escape_html(r->pool, ap_get_server_name_for_url(r)));
    apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip);  /* Apache */
    apr_table_addn(e, "SERVER_PORT",
                  apr_psprintf(r->pool, "%u", ap_get_server_port(r)));
    add_unless_null(e, "REMOTE_HOST",
                    ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL));
    apr_table_addn(e, "REMOTE_ADDR", r->useragent_ip);
    apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r));    /* Apache */
    apr_table_setn(e, "REQUEST_SCHEME", ap_http_scheme(r));
    apr_table_addn(e, "CONTEXT_PREFIX", ap_context_prefix(r));
    apr_table_addn(e, "CONTEXT_DOCUMENT_ROOT", ap_context_document_root(r));
    apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
    if (apr_table_get(r->notes, "proxy-noquery") && (q = ap_strchr(r->filename, '?'))) {
        *q = '\0';
        apr_table_addn(e, "SCRIPT_FILENAME", apr_pstrdup(r->pool, r->filename));
        *q = '?';
    }
    else {
        apr_table_addn(e, "SCRIPT_FILENAME", r->filename);  /* Apache */
    }

    rport = c->client_addr->port;
    apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport));

    if (r->user) {
        apr_table_addn(e, "REMOTE_USER", r->user);
    }
    else if (r->prev) {
        request_rec *back = r->prev;

        while (back) {
            if (back->user) {
                apr_table_addn(e, "REDIRECT_REMOTE_USER", back->user);
                break;
            }
            back = back->prev;
        }
    }
    add_unless_null(e, "AUTH_TYPE", r->ap_auth_type);
    env_temp = ap_get_remote_logname(r);
    if (env_temp) {
        apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, env_temp));
    }

    /* Apache custom error responses. If we have redirected set two new vars */

    if (r->prev) {
        /* PR#57785: reconstruct full URL here */
        apr_uri_t *uri = &r->prev->parsed_uri;
        if (!uri->scheme) {
            uri->scheme = (char*)ap_http_scheme(r->prev);
        }
        if (!uri->port) {
            uri->port = ap_get_server_port(r->prev);
            uri->port_str = apr_psprintf(r->pool, "%u", uri->port);
        }
        if (!uri->hostname) {
            uri->hostname = (char*)ap_get_server_name_for_url(r->prev);
        }
        add_unless_null(e, "REDIRECT_QUERY_STRING", r->prev->args);
        add_unless_null(e, "REDIRECT_URL",
                        apr_uri_unparse(r->pool, uri, 0));
    }

    if (e != r->subprocess_env) {
        apr_table_overlap(r->subprocess_env, e, APR_OVERLAP_TABLES_SET);
    }
}
Ejemplo n.º 11
0
API_EXPORT(void) ap_add_common_vars(request_rec *r)
{
    table *e;
    server_rec *s = r->server;
    conn_rec *c = r->connection;
    const char *rem_logname;
    char *env_path;
#if defined(WIN32) || defined(OS2)
    char *env_temp;
#endif
    const char *host;
    array_header *hdrs_arr = ap_table_elts(r->headers_in);
    table_entry *hdrs = (table_entry *) hdrs_arr->elts;
    int i;
    char servbuf[NI_MAXSERV];

    /* use a temporary table which we'll overlap onto
     * r->subprocess_env later
     */
    e = ap_make_table(r->pool, 25 + hdrs_arr->nelts);

    /* First, add environment vars from headers... this is as per
     * CGI specs, though other sorts of scripting interfaces see
     * the same vars...
     */

    for (i = 0; i < hdrs_arr->nelts; ++i) {
        if (!hdrs[i].key) {
	    continue;
	}

	/* A few headers are special cased --- Authorization to prevent
	 * rogue scripts from capturing passwords; content-type and -length
	 * for no particular reason.
	 */

	if (!strcasecmp(hdrs[i].key, "Content-type")) {
	    ap_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
	}
	else if (!strcasecmp(hdrs[i].key, "Content-length")) {
	    ap_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
	}
	/*
	 * You really don't want to disable this check, since it leaves you
	 * wide open to CGIs stealing passwords and people viewing them
	 * in the environment with "ps -e".  But, if you must...
	 */
#ifndef SECURITY_HOLE_PASS_AUTHORIZATION
	else if (!strcasecmp(hdrs[i].key, "Authorization") 
		 || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) {
	    continue;
	}
#endif
	else {
	    ap_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val);
	}
    }

    if (!(env_path = ap_pstrdup(r->pool, getenv("PATH")))) {
	env_path = DEFAULT_PATH;
    }

#ifdef WIN32
    if (env_temp = getenv("SystemRoot")) {
        ap_table_addn(e, "SystemRoot", env_temp);         
    }
    if (env_temp = getenv("COMSPEC")) {
        ap_table_addn(e, "COMSPEC", env_temp);            
    }
    if (env_temp = getenv("WINDIR")) {
        ap_table_addn(e, "WINDIR", env_temp);
    }
#endif

#ifdef OS2
    if ((env_temp = getenv("COMSPEC")) != NULL) {
        ap_table_addn(e, "COMSPEC", env_temp);            
    }
    if ((env_temp = getenv("ETC")) != NULL) {
        ap_table_addn(e, "ETC", env_temp);            
    }
    if ((env_temp = getenv("DPATH")) != NULL) {
        ap_table_addn(e, "DPATH", env_temp);            
    }
    if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) {
        ap_table_addn(e, "PERLLIB_PREFIX", env_temp);            
    }
#endif

    ap_table_addn(e, "PATH", env_path);
    ap_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
    ap_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version());
    ap_table_addn(e, "SERVER_NAME", 
		  ap_escape_html(r->pool,ap_get_server_name(r)));
    ap_table_addn(e, "SERVER_ADDR", r->connection->local_ip);	/* Apache */
    ap_table_addn(e, "SERVER_PORT",
		  ap_psprintf(r->pool, "%u", ap_get_server_port(r)));
    host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST);
    if (host) {
	ap_table_addn(e, "REMOTE_HOST", host);
    }
    ap_table_addn(e, "REMOTE_ADDR", c->remote_ip);
    ap_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r));	/* Apache */
    ap_table_addn(e, "SERVER_ADMIN", s->server_admin);	/* Apache */
    ap_table_addn(e, "SCRIPT_FILENAME", r->filename);	/* Apache */

    servbuf[0] = '\0';
    if (!getnameinfo((struct sockaddr *)&c->remote_addr,
#ifndef HAVE_SOCKADDR_LEN
		     SA_LEN((struct sockaddr *)&c->remote_addr),
#else
		     c->remote_addr.ss_len,
#endif
		     NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){
	ap_table_addn(e, "REMOTE_PORT", ap_pstrdup(r->pool, servbuf));
    }

    if (c->user) {
	ap_table_addn(e, "REMOTE_USER", c->user);
    }
    if (c->ap_auth_type) {
	ap_table_addn(e, "AUTH_TYPE", c->ap_auth_type);
    }
    rem_logname = ap_get_remote_logname(r);
    if (rem_logname) {
	ap_table_addn(e, "REMOTE_IDENT", ap_pstrdup(r->pool, rem_logname));
    }

    /* Apache custom error responses. If we have redirected set two new vars */

    if (r->prev) {
        if (r->prev->args) {
	    ap_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args);
	}
	if (r->prev->uri) {
	    ap_table_addn(e, "REDIRECT_URL", r->prev->uri);
	}
    }

    ap_overlap_tables(r->subprocess_env, e, AP_OVERLAP_TABLES_SET);
}
Ejemplo n.º 12
0
/**
 * Writes request parameters to srun.
 */
static void
write_env(stream_t *s, request_rec *r, char *session_id)
{
  char buf[4096];
  int ch;
  int i;
  
  conn_rec *c = r->connection;
  const char *host;
  int port;
  int is_sub_request = 1;
  char *uri;

  /*
   * is_sub_request is always true, since we can't detect mod_rewrite
   * and mod_rewrite doesn't change the unparsed_uri.
   */
  if (is_sub_request)
    uri = r->uri; /* for mod_rewrite */
  else
    uri = r->unparsed_uri; /* #937 */
  
  for (i = 0; (ch = uri[i]) && ch != '?' && i + 1 < sizeof(buf); i++) 
    buf[i] = ch;
  if (session_id) {
    buf[i++] = *s->config->session_url_prefix;
    for (session_id++; *session_id && i + 1 < sizeof(buf); i++)
      buf[i] = *session_id++;
  }
  buf[i] = 0;
  cse_write_string(s, HMUX_URL, buf);

  cse_write_string(s, HMUX_METHOD, r->method);
  if (*s->config->alt_session_url_prefix && r->request_config) {
    char *suburi = ap_get_module_config(r->request_config, &caucho_module);

    if (suburi)
      uri = suburi;
  }
  cse_write_string(s, CSE_PROTOCOL, r->protocol);

  if (r->args)
    cse_write_string(s, CSE_QUERY_STRING, r->args);

  /* Gets the server name */
  host = ap_get_server_name(r);
  port = ap_get_server_port(r);

  cse_write_string(s, HMUX_SERVER_NAME, host);
  cse_write_string(s, CSE_SERVER_PORT, ap_psprintf(r->pool, "%u", port));

  host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST);
  if (host)
    cse_write_string(s, CSE_REMOTE_HOST, host);
  else
    cse_write_string(s, CSE_REMOTE_HOST, c->remote_ip);

  cse_write_string(s, CSE_REMOTE_ADDR, c->remote_ip);
  cse_write_string(s, CSE_REMOTE_PORT,
		   ap_psprintf(r->pool, "%d", ntohs(c->remote_addr.sin_port)));
  
  if (c->user)
    cse_write_string(s, CSE_REMOTE_USER, c->user);
  if (c->ap_auth_type)
    cse_write_string(s, CSE_AUTH_TYPE, c->ap_auth_type);
}
Ejemplo n.º 13
0
static void vhost_alias_interpolate(request_rec *r, const char *name,
				    const char *map, const char *uri)
{
    /* 0..9 9..0 */
    enum { MAXDOTS = 19 };
    const char *dots[MAXDOTS+1];
    int ndots;

    char buf[HUGE_STRING_LEN];
    char *dest, last;

    int N, M, Np, Mp, Nd, Md;
    const char *start, *end;

    const char *p;

    ndots = 0;
    dots[ndots++] = name-1; /* slightly naughty */
    for (p = name; *p; ++p){
	if (*p == '.' && ndots < MAXDOTS) {
	    dots[ndots++] = p;
	}
    }
    dots[ndots] = p;

    r->filename = NULL;
  
    dest = buf;
    last = '\0';
    while (*map) {
	if (*map != '%') {
	    /* normal characters */
	    vhost_alias_checkspace(r, buf, &dest, 1);
	    last = *dest++ = *map++;
	    continue;
	}
	/* we are in a format specifier */
	++map;
	/* can't be a slash */
	last = '\0';
	/* %% -> % */
	if (*map == '%') {
	    ++map;
	    vhost_alias_checkspace(r, buf, &dest, 1);
	    *dest++ = '%';
	    continue;
	}
	/* port number */
	if (*map == 'p') {
	    ++map;
	    /* no. of decimal digits in a short plus one */
	    vhost_alias_checkspace(r, buf, &dest, 7);
	    dest += apr_snprintf(dest, 7, "%d", ap_get_server_port(r));
	    continue;
	}
	/* deal with %-N+.-M+ -- syntax is already checked */
	N = M = 0;   /* value */
	Np = Mp = 0; /* is there a plus? */
	Nd = Md = 0; /* is there a dash? */
	if (*map == '-') ++map, Nd = 1;
	N = *map++ - '0';
	if (*map == '+') ++map, Np = 1;
	if (*map == '.') {
	    ++map;
	    if (*map == '-') {
		++map, Md = 1;
	    }
	    M = *map++ - '0';
	    if (*map == '+') {
		++map, Mp = 1;
	    }
	}
	/* note that N and M are one-based indices, not zero-based */
	start = dots[0]+1; /* ptr to the first character */
	end = dots[ndots]; /* ptr to the character after the last one */
	if (N != 0) {
	    if (N > ndots) {
		start = "_";
		end = start+1;
	    }
	    else if (!Nd) {
		start = dots[N-1]+1;
		if (!Np) {
		    end = dots[N];
		}
	    }
	    else {
		if (!Np) {
		    start = dots[ndots-N]+1;
		}
		end = dots[ndots-N+1];
	    }
	}
	if (M != 0) {
	    if (M > end - start) {
		start = "_";
		end = start+1;
	    }
	    else if (!Md) {
		start = start+M-1;
		if (!Mp) {
		    end = start+1;
		}
	    }
	    else {
		if (!Mp) {
		    start = end-M;
		}
		end = end-M+1;
	    }
	}
	vhost_alias_checkspace(r, buf, &dest, end - start);
	for (p = start; p < end; ++p) {
	    *dest++ = apr_tolower(*p);
	}
    }
    *dest = '\0';
    /* no double slashes */
    if (last == '/') {
	++uri;
    }

    if (r->filename) {
	r->filename = apr_pstrcat(r->pool, r->filename, buf, uri, NULL);
    }
    else {
	r->filename = apr_pstrcat(r->pool, buf, uri, NULL);
    }
}
Ejemplo n.º 14
0
/*
 * This handles http:// URLs, and other URLs using a remote proxy over http
 * If proxyhost is NULL, then contact the server directly, otherwise
 * go via the proxy.
 * Note that if a proxy is used, then URLs other than http: can be accessed,
 * also, if we have trouble which is clearly specific to the proxy, then
 * we return DECLINED so that we can try another proxy. (Or the direct
 * route.)
 */
int ap_proxy_http_handler(request_rec *r, cache_req *c, char *url,
                              const char *proxyhost, int proxyport)
{
    const char *strp;
    char *strp2;
    const char *err, *desthost;
    int i, j, sock,/* len,*/ backasswards;
    table *req_hdrs, *resp_hdrs;
    array_header *reqhdrs_arr;
    table_entry *reqhdrs_elts;
    BUFF *f;
    char buffer[HUGE_STRING_LEN];
    char portstr[32];
    pool *p = r->pool;
    int chunked = 0, destport = 0;
    char *destportstr = NULL;
    const char *urlptr = NULL;
    const char *datestr, *urlstr;
    struct addrinfo hints, *res, *res0;
    int error;
    int result, major, minor;
    const char *content_length;
    const char *peer;
    int destportstrtonum;
    const char *errstr;

    void *sconf = r->server->module_config;
    proxy_server_conf *conf =
    (proxy_server_conf *)ap_get_module_config(sconf, &proxy_module);
    struct noproxy_entry *npent = (struct noproxy_entry *) conf->noproxies->elts;
    struct nocache_entry *ncent = (struct nocache_entry *) conf->nocaches->elts;
    int nocache = 0;

    if (conf->cache.root == NULL)
        nocache = 1;

    /* We break the URL into host, port, path-search */

    urlptr = strstr(url, "://");
    if (urlptr == NULL)
        return HTTP_BAD_REQUEST;
    destport = DEFAULT_HTTP_PORT;
    urlptr += 3;
    ap_hook_use("ap::mod_proxy::http::handler::set_destport", 
                AP_HOOK_SIG2(int,ptr), 
                AP_HOOK_TOPMOST,
                &destport, r);
    ap_snprintf(portstr, sizeof(portstr), "%d", destport);
    destportstr = portstr;
    strp = strchr(urlptr, '/');
    if (strp == NULL) {
        desthost = ap_pstrdup(p, urlptr);
        urlptr = "/";
    }
    else {
        char *q = ap_palloc(p, strp - urlptr + 1);
        memcpy(q, urlptr, strp - urlptr);
        q[strp - urlptr] = '\0';
        urlptr = strp;
        desthost = q;
    }
    if (*desthost == '['){
      char *u = strrchr(desthost+1, ']');
      if (u){
          desthost++;
          *u = '\0';
          if (*(u+1) == ':'){ /* [host]:xx */
              strp2 = u+1;
          }
          else if (*(u+1) == '\0'){   /* [host] */
              strp2 = NULL;
          }
          else
              return HTTP_BAD_REQUEST;
      }
      else
          return HTTP_BAD_REQUEST;
    }
    else
       strp2 = strrchr(desthost, ':');

    if (strp2 != NULL) {
        *(strp2++) = '\0';
        if (ap_isdigit(*strp2))
            destportstr = strp2;
    }

    /* Make sure peer is always set to prevent a segfault in the SSL handler */
    peer = desthost;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = PF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;
    error = getaddrinfo(desthost, destportstr, &hints, &res0);
    if (error && proxyhost == NULL) {
      return ap_proxyerror(r, HTTP_INTERNAL_SERVER_ERROR,
                  gai_strerror(error));       /* give up */
     }
 
      /* check if ProxyBlock directive on this host */
      for (i = 0; i < conf->noproxies->nelts; i++) {
      int fail;
      struct sockaddr_in *sin;

      fail = 0;
      if (npent[i].name != NULL && strstr(desthost, npent[i].name))
          fail++;
      if (npent[i].name != NULL && strcmp(npent[i].name, "*") == 0)
          fail++;
      for (res = res0; res; res = res->ai_next) {
          switch (res->ai_family) {
          case AF_INET:
              sin = (struct sockaddr_in *)res->ai_addr;
              if (sin->sin_addr.s_addr == npent[i].addr.s_addr)
                  fail++;
              break;
		
          }
      }
      if (fail) {
          if (res0 != NULL)
              freeaddrinfo(res0);
          return ap_proxyerror(r, HTTP_FORBIDDEN,
                               "Connect to remote machine blocked");
      }
    }
    if (proxyhost != NULL) {
      char pbuf[10];

      if (res0 != NULL)
          freeaddrinfo(res0);

      ap_snprintf(pbuf, sizeof(pbuf), "%d", proxyport);
      memset(&hints, 0, sizeof(hints));
      hints.ai_family = PF_UNSPEC;
      hints.ai_socktype = SOCK_STREAM;
      hints.ai_protocol = IPPROTO_TCP;
      error = getaddrinfo(proxyhost, pbuf, &hints, &res0);
      if (error)
          return DECLINED;    /* try another */
    }

    /* check if ProxyBlock directive on this host */
    for (i = 0; i < conf->noproxies->nelts; i++) {
	peer =  ap_psprintf(p, "%s:%s", desthost, destportstr);  
    }


    /*
     * we have worked out who exactly we are going to connect to, now make
     * that connection...
     */
     sock = i = -1;
     for (res = res0; res; res = res->ai_next) {
       sock = ap_psocket(p, res->ai_family, res->ai_socktype,
           res->ai_protocol);
       if (sock < 0)
           continue;

      if (conf->recv_buffer_size) {
          if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF,
                         (const char *)&conf->recv_buffer_size, sizeof(int))
              == -1) {
              ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
                            "setsockopt(SO_RCVBUF): Failed to set ProxyReceiveBufferSize, using default");
          }
      }

      i = ap_proxy_doconnect(sock, res->ai_addr, r);
      if (i == 0)
          break;
      ap_pclosesocket(p, sock);
    }
    freeaddrinfo(res0);

    if (i == -1) {
        if (proxyhost != NULL)
            return DECLINED;    /* try again another way */
        else
            return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,
                                    "Could not connect to remote machine: ",
                                                    strerror(errno), NULL));
    }

    /* record request_time for HTTP/1.1 age calculation */
    c->req_time = time(NULL);

    /*
     * build upstream-request headers by stripping r->headers_in from
     * connection specific headers. We must not remove the Connection: header
     * from r->headers_in, we still have to react to Connection: close
     */
    req_hdrs = ap_copy_table(r->pool, r->headers_in);
    ap_proxy_clear_connection(r->pool, req_hdrs);

    /*
     * At this point, we start sending the HTTP/1.1 request to the remote
     * server (proxy or otherwise).
     */
    f = ap_bcreate(p, B_RDWR | B_SOCKET);
    ap_bpushfd(f, sock, sock);

    {
        char *errmsg = NULL;
        ap_hook_use("ap::mod_proxy::http::handler::new_connection", 
                    AP_HOOK_SIG4(ptr,ptr,ptr,ptr), 
                    AP_HOOK_DECLINE(NULL),
                    &errmsg, r, f, peer);
        if (errmsg != NULL)
            return ap_proxyerror(r, HTTP_BAD_GATEWAY, errmsg);
    }

    ap_hard_timeout("proxy send", r);
    ap_bvputs(f, r->method, " ", proxyhost ? url : urlptr, " HTTP/1.1" CRLF,
              NULL);
    {
	int rc = DECLINED;
	ap_hook_use("ap::mod_proxy::http::handler::write_host_header", 
		    AP_HOOK_SIG6(int,ptr,ptr,ptr,ptr,ptr), 
		    AP_HOOK_DECLINE(DECLINED),
		    &rc, r, f, desthost, destportstr, destportstr);
        if (rc == DECLINED) {
	    destportstrtonum = strtonum(destportstr, 0, 65535, &errstr);
	    if (errstr)
		errx(1, "The destination port is %s: %s", errstr, destportstr);

	    if (destportstr != NULL && destportstrtonum != destport)
		ap_bvputs(f, "Host: ", desthost, ":", destportstr, CRLF, NULL);
	    else
		ap_bvputs(f, "Host: ", desthost, CRLF, NULL);
        }
    }

    if (conf->viaopt == via_block) {
        /* Block all outgoing Via: headers */
        ap_table_unset(req_hdrs, "Via");
    }
    else if (conf->viaopt != via_off) {
        /* Create a "Via:" request header entry and merge it */
        i = ap_get_server_port(r);
        if (ap_is_default_port(i, r)) {
            strlcpy(portstr, "", sizeof(portstr));
        }
        else {
            ap_snprintf(portstr, sizeof portstr, ":%d", i);
        }
        /* Generate outgoing Via: header with/without server comment: */
        ap_table_mergen(req_hdrs, "Via",
                        (conf->viaopt == via_full)
                        ? ap_psprintf(p, "%d.%d %s%s (%s)",
                                      HTTP_VERSION_MAJOR(r->proto_num),
                                      HTTP_VERSION_MINOR(r->proto_num),
                                      ap_get_server_name(r), portstr,
                                      SERVER_BASEVERSION)
                        : ap_psprintf(p, "%d.%d %s%s",
                                      HTTP_VERSION_MAJOR(r->proto_num),
                                      HTTP_VERSION_MINOR(r->proto_num),
                                      ap_get_server_name(r), portstr)
            );
    }

    /* the X-* headers are only added if we are a reverse
     * proxy, otherwise we would be giving away private information.
     */
    if (r->proxyreq == PROXY_PASS) {
        const char *buf;

        /*
         * Add X-Forwarded-For: so that the upstream has a chance to determine,
         * where the original request came from.
         */
        ap_table_mergen(req_hdrs, "X-Forwarded-For", r->connection->remote_ip);

        /* Add X-Forwarded-Host: so that upstream knows what the
         * original request hostname was.
         */
        if ((buf = ap_table_get(r->headers_in, "Host"))) {
            ap_table_mergen(req_hdrs, "X-Forwarded-Host", buf);
        }

        /* Add X-Forwarded-Server: so that upstream knows what the
         * name of this proxy server is (if there are more than one)
         * XXX: This duplicates Via: - do we strictly need it?
         */
        ap_table_mergen(req_hdrs, "X-Forwarded-Server", r->server->server_hostname);
    } 

    /* we don't yet support keepalives - but we will soon, I promise! */
    ap_table_set(req_hdrs, "Connection", "close");

    reqhdrs_arr = ap_table_elts(req_hdrs);
    reqhdrs_elts = (table_entry *)reqhdrs_arr->elts;
    for (i = 0; i < reqhdrs_arr->nelts; i++) {
        if (reqhdrs_elts[i].key == NULL || reqhdrs_elts[i].val == NULL

        /*
         * Clear out hop-by-hop request headers not to send: RFC2616 13.5.1
         * says we should strip these headers:
         */
            || !strcasecmp(reqhdrs_elts[i].key, "Host") /* Already sent */
            || !strcasecmp(reqhdrs_elts[i].key, "Keep-Alive")
            || !strcasecmp(reqhdrs_elts[i].key, "TE")
            || !strcasecmp(reqhdrs_elts[i].key, "Trailer")
            || !strcasecmp(reqhdrs_elts[i].key, "Transfer-Encoding")
            || !strcasecmp(reqhdrs_elts[i].key, "Upgrade")
        /*
         * XXX: @@@ FIXME: "Proxy-Authorization" should *only* be suppressed
         * if THIS server requested the authentication, not when a frontend
         * proxy requested it!
         * 
         * The solution to this problem is probably to strip out the
         * Proxy-Authorisation header in the authorisation code itself, not
         * here. This saves us having to signal somehow whether this request
         * was authenticated or not.
         */
            || !strcasecmp(reqhdrs_elts[i].key, "Proxy-Authorization"))
            continue;
        ap_bvputs(f, reqhdrs_elts[i].key, ": ", reqhdrs_elts[i].val, CRLF, NULL);
    }

    /* the obligatory empty line to mark the end of the headers */
    ap_bputs(CRLF, f);

    /* and flush the above away */
    ap_bflush(f);

    /* and kill the send timeout */
    ap_kill_timeout(r);


    /* read the request data, and pass it to the backend.
     * we might encounter a stray 100-continue reponse from a PUT or POST,
     * if this happens we ignore the 100 continue status line and read the
     * response again.
     */
    {
        /* send the request data, if any. */
        ap_hard_timeout("proxy receive request data", r);
        if (ap_should_client_block(r)) {
            while ((i = ap_get_client_block(r, buffer, sizeof buffer)) > 0) {
                ap_reset_timeout(r);
                ap_bwrite(f, buffer, i);
            }
        }
        ap_bflush(f);
        ap_kill_timeout(r);


        /* then, read a response line */
        ap_hard_timeout("proxy receive response status line", r);
        result = ap_proxy_read_response_line(f, r, buffer, sizeof(buffer)-1, &backasswards, &major, &minor);
        ap_kill_timeout(r);

        /* trap any errors */
        if (result != OK) {
            ap_bclose(f);
            return result;
        }

        /* if this response was 100-continue, a stray response has been caught.
         * read the line again for the real response
         */
        if (r->status == 100) {
            ap_hard_timeout("proxy receive response status line", r);
            result = ap_proxy_read_response_line(f, r, buffer, sizeof(buffer)-1, &backasswards, &major, &minor);
            ap_kill_timeout(r);

            /* trap any errors */
            if (result != OK) {
                ap_bclose(f);
                return result;
            }
        }
    }


    /*
     * We have our response status line from the convoluted code above,
     * now we read the headers to continue.
     */
    ap_hard_timeout("proxy receive response headers", r);

    /*
     * Is it an HTTP/1 response? Do some sanity checks on the response. (This
     * is buggy if we ever see an HTTP/1.10)
     */
    if (backasswards == 0) {

        /* read the response headers. */
        /* N.B. for HTTP/1.0 clients, we have to fold line-wrapped headers */
        /* Also, take care with headers with multiple occurences. */

        resp_hdrs = ap_proxy_read_headers(r, buffer, sizeof(buffer), f);
        if (resp_hdrs == NULL) {
            ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, r->server,
                         "proxy: Bad HTTP/%d.%d header returned by %s (%s)",
                         major, minor, r->uri, r->method);
            resp_hdrs = ap_make_table(p, 20);
            nocache = 1;        /* do not cache this broken file */
        }

        /* handle Via header in the response */
        if (conf->viaopt != via_off && conf->viaopt != via_block) {
            /* Create a "Via:" response header entry and merge it */
            i = ap_get_server_port(r);
            if (ap_is_default_port(i, r)) {
                strlcpy(portstr, "", sizeof(portstr));
            }
            else {
                ap_snprintf(portstr, sizeof portstr, ":%d", i);
            }
            ap_table_mergen((table *)resp_hdrs, "Via",
                            (conf->viaopt == via_full)
                            ? ap_psprintf(p, "%d.%d %s%s (%s)",
                                          major, minor,
                                          ap_get_server_name(r), portstr,
                                          SERVER_BASEVERSION)
                            : ap_psprintf(p, "%d.%d %s%s",
                                          major, minor,
                                          ap_get_server_name(r), portstr)
                );
        }

        /* is this content chunked? */
        chunked = ap_find_last_token(r->pool,
                                     ap_table_get(resp_hdrs, "Transfer-Encoding"),
                                     "chunked");

        /* strip hop-by-hop headers defined by Connection and RFC2616 */
        ap_proxy_clear_connection(p, resp_hdrs);

        content_length = ap_table_get(resp_hdrs, "Content-Length");
        if (content_length != NULL) {
            c->len = ap_strtol(content_length, NULL, 10);

	    if (c->len < 0) {
		ap_kill_timeout(r);
		return ap_proxyerror(r, HTTP_BAD_GATEWAY, ap_pstrcat(r->pool,
				     "Invalid Content-Length from remote server",
                                      NULL));
	    }
        }

    }
    else {
        /* an http/0.9 response */

        /* no headers */
        resp_hdrs = ap_make_table(p, 20);
    }

    ap_kill_timeout(r);

    /*
     * HTTP/1.1 requires us to accept 3 types of dates, but only generate one
     * type
     */
    /*
     * we SET the dates here, obliterating possible multiple dates, as only
     * one of each date makes sense in each response.
     */
    if ((datestr = ap_table_get(resp_hdrs, "Date")) != NULL)
        ap_table_set(resp_hdrs, "Date", ap_proxy_date_canon(p, datestr));
    if ((datestr = ap_table_get(resp_hdrs, "Last-Modified")) != NULL)
        ap_table_set(resp_hdrs, "Last-Modified", ap_proxy_date_canon(p, datestr));
    if ((datestr = ap_table_get(resp_hdrs, "Expires")) != NULL)
        ap_table_set(resp_hdrs, "Expires", ap_proxy_date_canon(p, datestr));

    /* handle the ProxyPassReverse mappings */
    if ((urlstr = ap_table_get(resp_hdrs, "Location")) != NULL)
        ap_table_set(resp_hdrs, "Location", proxy_location_reverse_map(r, urlstr));
    if ((urlstr = ap_table_get(resp_hdrs, "URI")) != NULL)
        ap_table_set(resp_hdrs, "URI", proxy_location_reverse_map(r, urlstr));
    if ((urlstr = ap_table_get(resp_hdrs, "Content-Location")) != NULL)
        ap_table_set(resp_hdrs, "Content-Location", proxy_location_reverse_map(r, urlstr));

/* check if NoCache directive on this host */
  {
    struct sockaddr_in *sin;
    struct sockaddr_in6 *sin6;

    if (nocache == 0) {
	for (i = 0; i < conf->nocaches->nelts; i++) {
	    if (ncent[i].name != NULL && 
		(ncent[i].name[0] == '*' ||
		 strstr(desthost, ncent[i].name) != NULL)) {
		nocache = 1;
		break;
	    }
	    switch (res->ai_addr->sa_family) {
	    case AF_INET:
		sin = (struct sockaddr_in *)res->ai_addr;
		if (sin->sin_addr.s_addr == ncent[i].addr.s_addr) {
		    nocache = 1;
		    break;
		}
	    }
	}

        /* update the cache file, possibly even fulfilling the request if
         * it turns out a conditional allowed us to serve the object from the
         * cache...
         */
        i = ap_proxy_cache_update(c, resp_hdrs, !backasswards, nocache);
        if (i != DECLINED) {
            ap_bclose(f);
            return i;
        }

        /* write status line and headers to the cache file */
        ap_proxy_write_headers(c, ap_pstrcat(p, "HTTP/1.1 ", r->status_line, NULL), resp_hdrs);
    }
  }

    /* Setup the headers for our client from upstreams response-headers */
    ap_proxy_table_replace(r->headers_out, resp_hdrs);
    /* Add X-Cache header - be careful not to obliterate any upstream headers */
    ap_table_mergen(r->headers_out, "X-Cache",
                    ap_pstrcat(r->pool, "MISS from ",
                               ap_get_server_name(r), NULL));
    /* The Content-Type of this response is the upstream one. */
    r->content_type = ap_table_get(r->headers_out, "Content-Type");
    ap_log_error(APLOG_MARK, APLOG_DEBUG | APLOG_NOERRNO, r->server, "Content-Type: %s", r->content_type);

    /* finally output the headers to the client */
    ap_send_http_header(r);

    /*
     * Is it an HTTP/0.9 respose? If so, send the extra data we read from
     * upstream as the start of the reponse to client
     */
/* FIXME: This code is broken: we try and write a buffer and length that
 * were never intelligently initialised. Rather have a bit of broken protocol
 * handling for now than broken code.
 */
/*
    if (backasswards) {
        ap_hard_timeout("proxy send assbackward", r);

        ap_bwrite(r->connection->client, buffer, len);
        if (c != NULL && c->fp != NULL && ap_bwrite(c->fp, buffer, len) != len) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, c->req,
                      "proxy: error writing extra data to %s", c->tempfile);
            c = ap_proxy_cache_error(c);
        }
        ap_kill_timeout(r);
    }
*/

/* send body */
/* if header only, then cache will be NULL */
/* HTTP/1.0 tells us to read to EOF, rather than content-length bytes */
/* XXX CHANGEME: We want to eventually support keepalives, which means
 * we must read content-length bytes... */
    if (!r->header_only) {
/* we need to set this for ap_proxy_send_fb()... */
        c->cache_completion = conf->cache.cache_completion;

/* XXX CHECKME: c->len should be the expected content length, or -1 if the
 * content length is not known. We need to make 100% sure c->len is always
 * set correctly before we get here to correctly do keepalive.
 */
        ap_proxy_send_fb(f, r, c, c->len, 0, chunked, conf->io_buffer_size);
    }

    /* ap_proxy_send_fb() closes the socket f for us */

    ap_proxy_cache_tidy(c);

    ap_proxy_garbage_coll(r);
    return OK;
}
Ejemplo n.º 15
0
/* This function must remain safe to use for a non-SSL connection. */
char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r, char *var)
{
    SSLModConfigRec *mc = myModConfig(s);
    const char *result;
    BOOL resdup;
    apr_time_exp_t tm;

    result = NULL;
    resdup = TRUE;

    /*
     * When no pool is given try to find one
     */
    if (p == NULL) {
        if (r != NULL)
            p = r->pool;
        else if (c != NULL)
            p = c->pool;
        else
            p = mc->pPool;
    }

    /*
     * Request dependent stuff
     */
    if (r != NULL) {
        switch (var[0]) {
        case 'H':
        case 'h':
            if (strcEQ(var, "HTTP_USER_AGENT"))
                result = apr_table_get(r->headers_in, "User-Agent");
            else if (strcEQ(var, "HTTP_REFERER"))
                result = apr_table_get(r->headers_in, "Referer");
            else if (strcEQ(var, "HTTP_COOKIE"))
                result = apr_table_get(r->headers_in, "Cookie");
            else if (strcEQ(var, "HTTP_FORWARDED"))
                result = apr_table_get(r->headers_in, "Forwarded");
            else if (strcEQ(var, "HTTP_HOST"))
                result = apr_table_get(r->headers_in, "Host");
            else if (strcEQ(var, "HTTP_PROXY_CONNECTION"))
                result = apr_table_get(r->headers_in, "Proxy-Connection");
            else if (strcEQ(var, "HTTP_ACCEPT"))
                result = apr_table_get(r->headers_in, "Accept");
            else if (strlen(var) > 5 && strcEQn(var, "HTTP:", 5))
                /* all other headers from which we are still not know about */
                result = apr_table_get(r->headers_in, var+5);
            break;

        case 'R':
        case 'r':
            if (strcEQ(var, "REQUEST_METHOD"))
                result = r->method;
            else if (strcEQ(var, "REQUEST_SCHEME"))
                result = ap_http_scheme(r);
            else if (strcEQ(var, "REQUEST_URI"))
                result = r->uri;
            else if (strcEQ(var, "REQUEST_FILENAME"))
                result = r->filename;
            else if (strcEQ(var, "REMOTE_ADDR"))
                result = r->useragent_ip;
            else if (strcEQ(var, "REMOTE_HOST"))
                result = ap_get_useragent_host(r, REMOTE_NAME, NULL);
            else if (strcEQ(var, "REMOTE_IDENT"))
                result = ap_get_remote_logname(r);
            else if (strcEQ(var, "REMOTE_USER"))
                result = r->user;
            break;

        case 'S':
        case 's':
            if (strcEQn(var, "SSL", 3)) break; /* shortcut common case */

            if (strcEQ(var, "SERVER_ADMIN"))
                result = r->server->server_admin;
            else if (strcEQ(var, "SERVER_NAME"))
                result = ap_get_server_name_for_url(r);
            else if (strcEQ(var, "SERVER_PORT"))
                result = apr_psprintf(p, "%u", ap_get_server_port(r));
            else if (strcEQ(var, "SERVER_PROTOCOL"))
                result = r->protocol;
            else if (strcEQ(var, "SCRIPT_FILENAME"))
                result = r->filename;
            break;

        default:
            if (strcEQ(var, "PATH_INFO"))
                result = r->path_info;
            else if (strcEQ(var, "QUERY_STRING"))
                result = r->args;
            else if (strcEQ(var, "IS_SUBREQ"))
                result = (r->main != NULL ? "true" : "false");
            else if (strcEQ(var, "DOCUMENT_ROOT"))
                result = ap_document_root(r);
            else if (strcEQ(var, "AUTH_TYPE"))
                result = r->ap_auth_type;
            else if (strcEQ(var, "THE_REQUEST"))
                result = r->the_request;
            else if (strlen(var) > 4 && strcEQn(var, "ENV:", 4)) {
                result = apr_table_get(r->notes, var+4);
                if (result == NULL)
                    result = apr_table_get(r->subprocess_env, var+4);
            }
            break;
        }
    }

    /*
     * Connection stuff
     */
    if (result == NULL && c != NULL) {
        SSLConnRec *sslconn = ssl_get_effective_config(c);
        if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)
            && sslconn && sslconn->ssl)
            result = ssl_var_lookup_ssl(p, sslconn, r, var+4);
        else if (strcEQ(var, "HTTPS")) {
            if (sslconn && sslconn->ssl)
                result = "on";
            else
                result = "off";
        }
    }

    /*
     * Totally independent stuff
     */
    if (result == NULL) {
        if (strlen(var) > 12 && strcEQn(var, "SSL_VERSION_", 12))
            result = ssl_var_lookup_ssl_version(p, var+12);
        else if (strcEQ(var, "SERVER_SOFTWARE"))
            result = ap_get_server_banner();
        else if (strcEQ(var, "API_VERSION")) {
            result = apr_itoa(p, MODULE_MAGIC_NUMBER_MAJOR);
            resdup = FALSE;
        }
        else if (strcEQ(var, "TIME_YEAR")) {
            apr_time_exp_lt(&tm, apr_time_now());
            result = apr_psprintf(p, "%02d%02d",
                                 (tm.tm_year / 100) + 19, tm.tm_year % 100);
            resdup = FALSE;
        }
#define MKTIMESTR(format, tmfield) \
            apr_time_exp_lt(&tm, apr_time_now()); \
            result = apr_psprintf(p, format, tm.tmfield); \
            resdup = FALSE;
        else if (strcEQ(var, "TIME_MON")) {
            MKTIMESTR("%02d", tm_mon+1)
        }
        else if (strcEQ(var, "TIME_DAY")) {
            MKTIMESTR("%02d", tm_mday)
        }
        else if (strcEQ(var, "TIME_HOUR")) {
            MKTIMESTR("%02d", tm_hour)
        }
        else if (strcEQ(var, "TIME_MIN")) {
            MKTIMESTR("%02d", tm_min)
        }
        else if (strcEQ(var, "TIME_SEC")) {
            MKTIMESTR("%02d", tm_sec)
        }
        else if (strcEQ(var, "TIME_WDAY")) {
            MKTIMESTR("%d", tm_wday)
        }
        else if (strcEQ(var, "TIME")) {
            apr_time_exp_lt(&tm, apr_time_now());
            result = apr_psprintf(p,
                        "%02d%02d%02d%02d%02d%02d%02d", (tm.tm_year / 100) + 19,
                        (tm.tm_year % 100), tm.tm_mon+1, tm.tm_mday,
                        tm.tm_hour, tm.tm_min, tm.tm_sec);
            resdup = FALSE;
        }
        /* all other env-variables from the parent Apache process */
        else if (strlen(var) > 4 && strcEQn(var, "ENV:", 4)) {
            result = getenv(var+4);
        }
    }

    if (result != NULL && resdup)
        result = apr_pstrdup(p, result);
    if (result == NULL)
        result = "";
    return (char *)result;
}
Ejemplo n.º 16
0
/**
 * Handle a request.
 */
static int
caucho_request(request_rec *r, config_t *config, resin_host_t *host,
	       unsigned int now)
{
  stream_t s;
  int retval;
  int code = -1;
  int session_index;
  int backup_index = 0;
  char *ip;
  srun_t *srun;

  if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)))
    return retval;

  session_index = get_session_index(config, r, &backup_index);
  ip = r->connection->REMOTE_IP;

  if (host) {
  }
  else if (config->manual_host) {
    host = config->manual_host;
  }
  else {
    host = cse_match_host(config,
			  ap_get_server_name(r),
			  ap_get_server_port(r),
			  now);
  }
    
  LOG(("%s:%d:caucho_request(): session index: %d\n",
       __FILE__, __LINE__, session_index));
  
  if (! host) {
    ERR(("%s:%d:caucho_request(): no host: %p\n",
	 __FILE__, __LINE__, host));
    
    return HTTP_SERVICE_UNAVAILABLE;
  }
  else if (! cse_open_connection(&s, &host->cluster,
				 session_index, backup_index,
				 now, r->pool)) {
    ERR(("%s:%d:caucho_request(): no connection: cluster(%p)\n",
	 __FILE__, __LINE__, &host->cluster));
    
    return HTTP_SERVICE_UNAVAILABLE;
  }

  srun = s.cluster_srun->srun;

  apr_thread_mutex_lock(srun->lock);
  srun->active_sockets++;
  apr_thread_mutex_unlock(srun->lock);
  
  code = write_request(&s, r, config, session_index, backup_index);

  apr_thread_mutex_lock(srun->lock);
  srun->active_sockets--;
  apr_thread_mutex_unlock(srun->lock);
  
  /* on failure, do not failover but simply fail */
  if (code == HMUX_QUIT)
    cse_free_idle(&s, now);
  else
    cse_close(&s, "no reuse");

  if (code != HMUX_QUIT && code != HMUX_EXIT) {
    ERR(("%s:%d:caucho_request(): protocol failure code:%d\n",
	 __FILE__, __LINE__, code));

    return HTTP_SERVICE_UNAVAILABLE;
  }
  else if (r->status == HTTP_SERVICE_UNAVAILABLE) {
    cse_close(&s, "close from 503");
    cse_srun_unavail(srun, now);

    return HTTP_SERVICE_UNAVAILABLE;
  }
  else {
    /*
     * See pages like jms/index.xtp
    int status = r->status;
    r->status = HTTP_OK;

    return status;
    */
    return OK;
  }
}
Ejemplo n.º 17
0
/**
 * Writes request parameters to srun.
 */
static void
write_env(stream_t *s, request_rec *r)
{
  char buf[4096];
  int ch;
  int i, j;
  
  conn_rec *c = r->connection;
  const char *host;
  const char *uri;
  int port;
  int is_sub_request = 1; /* for mod_rewrite */

  /*
   * is_sub_request is always true, since we can't detect mod_rewrite
   * and mod_rewrite doesn't change the unparsed_uri.
   */
  if (is_sub_request)
    uri = r->uri;
  else
    uri = r->unparsed_uri; /* #937 */

  j = 0;
  for (i = 0; (ch = uri[i]) && ch != '?' && j + 2 < sizeof(buf); i++) {
    if (ch == '%') { /* #1661 */
      buf[j++] = '%';
      buf[j++] = '2';
      buf[j++] = '5';
    }
    else
      buf[j++] = ch;
  }
  buf[j] = 0;

  cse_write_string(s, HMUX_URL, buf);

  cse_write_string(s, HMUX_METHOD, r->method);
  
  cse_write_string(s, CSE_PROTOCOL, r->protocol);

  if (r->args)
    cse_write_string(s, CSE_QUERY_STRING, r->args);

  /* Gets the server name */
  host = ap_get_server_name(r);
  port = ap_get_server_port(r);

  cse_write_string(s, HMUX_SERVER_NAME, host);
  sprintf(buf, "%u", port);
  cse_write_string(s, CSE_SERVER_PORT, buf);

  if (c->remote_host)
    cse_write_string(s, CSE_REMOTE_HOST, c->remote_host);
  else
    cse_write_string(s, CSE_REMOTE_HOST, c->REMOTE_IP);

  cse_write_string(s, CSE_REMOTE_ADDR, c->REMOTE_IP);
  sprintf(buf, "%u", ntohs(c->REMOTE_ADDR->port));
  cse_write_string(s, CSE_REMOTE_PORT, buf);

  if (r->user)
    cse_write_string(s, CSE_REMOTE_USER, r->user);
  if (r->ap_auth_type)
    cse_write_string(s, CSE_AUTH_TYPE, r->ap_auth_type);

  /* mod_ssl */
  if (g_ssl_lookup) {
    static char *vars[] = { "SSL_CLIENT_S_DN",
                            "SSL_CIPHER",
                            "SSL_CIPHER_EXPORT",
                            "SSL_PROTOCOL",
                            "SSL_CIPHER_USEKEYSIZE",
                            "SSL_CIPHER_ALGKEYSIZE",
                            0};
    char *var;
    int i;
    
    if ((var = g_ssl_lookup(r->pool, r->server, r->connection, r,
			    "SSL_CLIENT_CERT"))) {
      cse_write_string(s, CSE_CLIENT_CERT, var);
    }

    for (i = 0; vars[i]; i++) {
      if ((var = g_ssl_lookup(r->pool, r->server, r->connection, r,
			      vars[i]))) {
        cse_write_string(s, HMUX_HEADER, vars[i]);
        cse_write_string(s, HMUX_STRING, var);
      }
    }
  }
}
Ejemplo n.º 18
0
/**
 * Handle a request.
 */
static int
caucho_request(request_rec *r)
{
  config_t *config = cse_get_module_config(r);
  resin_host_t *host = 0;
  stream_t s;
  int retval;
  int keepalive = 0;
  int reuse;
  int session_index;
  int backup_index;
  char *ip;
  time_t now = r->request_time;
  char *session_id = 0;

  if (! config)
    return HTTP_SERVICE_UNAVAILABLE;
  
  if ((retval = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)))
    return retval;

  /* ap_soft_timeout("servlet request", r); */
  
  if (r->request_config && ! *config->alt_session_url_prefix &&
      ((session_id = ap_get_module_config(r->request_config, &caucho_module)) ||
       r->prev &&
       (session_id = ap_get_module_config(r->prev->request_config, &caucho_module)))) {
    /* *session_id = *config->session_url_prefix; */
  }

  session_index = get_session_index(config, r, &backup_index);
  ip = r->connection->remote_ip;
  
  if (host) {
  }
  else if (config->manual_host)
    host = config->manual_host;
  else {
    host = cse_match_host(config,
			  ap_get_server_name(r),
			  ap_get_server_port(r),
			  now);
  }

  if (! host ||
      ! cse_open_connection(&s, &host->cluster, session_index, backup_index,
                            now, r->pool)) {
    return HTTP_SERVICE_UNAVAILABLE;
  }

  reuse = write_request(&s, r, config, &host->cluster, &keepalive,
                        session_index, backup_index,
                        ip, session_id);
  /*
  ap_kill_timeout(r);
  */
  ap_rflush(r);

  if (reuse == HMUX_QUIT)
    cse_recycle(&s, now);
  else
    cse_close(&s, "no reuse");

  if (reuse == HTTP_SERVICE_UNAVAILABLE)
    return reuse;
  else
    return OK;
}
Ejemplo n.º 19
0
AP_DECLARE(void) ap_add_common_vars(request_rec *r)
{
    apr_table_t *e;
    server_rec *s = r->server;
    conn_rec *c = r->connection;
    const char *rem_logname;
    char *env_path;
#if defined(WIN32) || defined(OS2) || defined(BEOS)
    char *env_temp;
#endif
    const char *host;
    const apr_array_header_t *hdrs_arr = apr_table_elts(r->headers_in);
    const apr_table_entry_t *hdrs = (const apr_table_entry_t *) hdrs_arr->elts;
    int i;
    apr_port_t rport;

    /* use a temporary apr_table_t which we'll overlap onto
     * r->subprocess_env later
     * (exception: if r->subprocess_env is empty at the start,
     * write directly into it)
     */
    if (apr_is_empty_table(r->subprocess_env)) {
        e = r->subprocess_env;
    }
    else {
        e = apr_table_make(r->pool, 25 + hdrs_arr->nelts);
    }

    /* First, add environment vars from headers... this is as per
     * CGI specs, though other sorts of scripting interfaces see
     * the same vars...
     */

    for (i = 0; i < hdrs_arr->nelts; ++i) {
        if (!hdrs[i].key) {
            continue;
        }

        /* A few headers are special cased --- Authorization to prevent
         * rogue scripts from capturing passwords; content-type and -length
         * for no particular reason.
         */

        if (!strcasecmp(hdrs[i].key, "Content-type")) {
            apr_table_addn(e, "CONTENT_TYPE", hdrs[i].val);
        }
        else if (!strcasecmp(hdrs[i].key, "Content-length")) {
            apr_table_addn(e, "CONTENT_LENGTH", hdrs[i].val);
        }
        /*
         * You really don't want to disable this check, since it leaves you
         * wide open to CGIs stealing passwords and people viewing them
         * in the environment with "ps -e".  But, if you must...
         */
#ifndef SECURITY_HOLE_PASS_AUTHORIZATION
        else if (!strcasecmp(hdrs[i].key, "Authorization")
                 || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) {
            continue;
        }
#endif
        else {
            apr_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val);
        }
    }

    if (!(env_path = getenv("PATH"))) {
        env_path = DEFAULT_PATH;
    }
    apr_table_addn(e, "PATH", apr_pstrdup(r->pool, env_path));

#ifdef WIN32
    if ((env_temp = getenv("SystemRoot")) != NULL) {
        apr_table_addn(e, "SystemRoot", env_temp);
    }
    if ((env_temp = getenv("COMSPEC")) != NULL) {
        apr_table_addn(e, "COMSPEC", env_temp);
    }
    if ((env_temp = getenv("PATHEXT")) != NULL) {
        apr_table_addn(e, "PATHEXT", env_temp);
    }
    if ((env_temp = getenv("WINDIR")) != NULL) {
        apr_table_addn(e, "WINDIR", env_temp);
    }
#endif

#ifdef OS2
    if ((env_temp = getenv("COMSPEC")) != NULL) {
        apr_table_addn(e, "COMSPEC", env_temp);
    }
    if ((env_temp = getenv("ETC")) != NULL) {
        apr_table_addn(e, "ETC", env_temp);
    }
    if ((env_temp = getenv("DPATH")) != NULL) {
        apr_table_addn(e, "DPATH", env_temp);
    }
    if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) {
        apr_table_addn(e, "PERLLIB_PREFIX", env_temp);
    }
#endif

#ifdef BEOS
    if ((env_temp = getenv("LIBRARY_PATH")) != NULL) {
        apr_table_addn(e, "LIBRARY_PATH", env_temp);
    }
#endif

    apr_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r));
    apr_table_addn(e, "SERVER_SOFTWARE", ap_get_server_banner());
    apr_table_addn(e, "SERVER_NAME",
                   ap_escape_html(r->pool, ap_get_server_name(r)));
    apr_table_addn(e, "SERVER_ADDR", r->connection->local_ip);  /* Apache */
    apr_table_addn(e, "SERVER_PORT",
                  apr_psprintf(r->pool, "%u", ap_get_server_port(r)));
    host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST, NULL);
    if (host) {
        apr_table_addn(e, "REMOTE_HOST", host);
    }
    apr_table_addn(e, "REMOTE_ADDR", c->remote_ip);
    apr_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r));    /* Apache */
    apr_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */
    apr_table_addn(e, "SCRIPT_FILENAME", r->filename);  /* Apache */

    rport = c->remote_addr->port;
    apr_table_addn(e, "REMOTE_PORT", apr_itoa(r->pool, rport));

    if (r->user) {
        apr_table_addn(e, "REMOTE_USER", r->user);
    }
    else if (r->prev) {
        request_rec *back = r->prev;

        while (back) {
            if (back->user) {
                apr_table_addn(e, "REDIRECT_REMOTE_USER", back->user);
                break;
            }
            back = back->prev;
        }
    }
    if (r->ap_auth_type) {
        apr_table_addn(e, "AUTH_TYPE", r->ap_auth_type);
    }
    rem_logname = ap_get_remote_logname(r);
    if (rem_logname) {
        apr_table_addn(e, "REMOTE_IDENT", apr_pstrdup(r->pool, rem_logname));
    }

    /* Apache custom error responses. If we have redirected set two new vars */

    if (r->prev) {
        if (r->prev->args) {
            apr_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args);
        }
        if (r->prev->uri) {
            apr_table_addn(e, "REDIRECT_URL", r->prev->uri);
        }
    }

    if (e != r->subprocess_env) {
      apr_table_overlap(r->subprocess_env, e, APR_OVERLAP_TABLES_SET);
    }
}
Ejemplo n.º 20
0
static int
ipp_handler(request_rec *r)
{
	papi_attribute_t **request = NULL, **response = NULL;
	IPPListenerConfig *config;
	papi_status_t status;
	int ret;

	/* Really, IPP is all POST requests */
	if (r->method_number != M_POST)
		return (DECLINED);

#ifndef APACHE2
	/*
	 * An IPP request must have a MIME type of "application/ipp"
	 * (RFC-2910, Section 4, page 19).  If it doesn't match this
	 * MIME type, we should decline the request and let someone else
	 * try and handle it.
	 */
	if (r->headers_in != NULL) {
		char *mime_type = (char *)ap_table_get(r->headers_in,
							"Content-Type");

		if ((mime_type == NULL) ||
		    (strcasecmp(mime_type, "application/ipp") != 0))
			return (DECLINED);
	}
#endif
	/* CHUNKED_DECHUNK might not work right for IPP? */
	if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK)
		return (ret);

	if (!ap_should_client_block(r))
		return (HTTP_INTERNAL_SERVER_ERROR);

#ifndef APACHE2
	ap_soft_timeout("ipp_module: read/reply request ", r);
#endif
	/* read the IPP request off the network */
	status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST);

	if (status != PAPI_OK)
		_log_rerror(APLOG_MARK, APLOG_ERR, r,
			"read failed: %s\n", papiStatusString(status));
#ifdef DEBUG
	papiAttributeListPrint(stderr, request, "request (%d)  ", getpid());
#endif

	(void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
		"originating-host", (char *)
#ifdef APACHE2
		ap_get_remote_host
			(r->connection, r->per_dir_config, REMOTE_NAME, NULL));
#else
		ap_get_remote_host
			(r->connection, r->per_dir_config, REMOTE_NAME));
#endif

	(void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
				"uri-port", ap_get_server_port(r));
	if (r->headers_in != NULL) {
		char *host = (char *)ap_table_get(r->headers_in, "Host");

		if ((host == NULL) || (host[0] == '\0'))
			host = (char *)ap_get_server_name(r);

		(void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
				"uri-host", host);
	}
	(void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
				"uri-path", r->uri);

	config = ap_get_module_config(r->per_dir_config, &ipp_module);
	if (config != NULL) {
		(void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
				"conformance", config->conformance);
		(void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL,
				"operations", config->operations);
		if (config->default_user != NULL)
			(void) papiAttributeListAddString(&request,
						PAPI_ATTR_EXCL, "default-user",
						config->default_user);
		if (config->default_svc != NULL)
			(void) papiAttributeListAddString(&request,
					PAPI_ATTR_EXCL, "default-service",
					config->default_svc);
	}

	/*
	 * For Trusted Solaris, pass the fd number of the socket connection
	 * to the backend so the it can be forwarded to the backend print
	 * service to retrieve the sensativity label off of a multi-level
	 * port.
	 */
	(void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
			"peer-socket", ap_bfileno(r->connection->client, B_RD));

	/* process the request */
	status = ipp_process_request(request, &response, read_data, r);
	if (status != PAPI_OK) {
		errno = 0;
		_log_rerror(APLOG_MARK, APLOG_ERR, r,
			"request failed: %s\n", papiStatusString(status));
		discard_data(r);
	}
#ifdef DEBUG
	fprintf(stderr, "processing result: %s\n", papiStatusString(status));
	papiAttributeListPrint(stderr, response, "response (%d)  ", getpid());
#endif

	/*
	 * If the client is using chunking and we have not yet received the
	 * final "0" sized chunk, we need to discard any data that may
	 * remain in the post request.
	 */
	if ((r->read_chunked != 0) &&
	    (ap_table_get(r->headers_in, "Content-Length") == NULL))
		discard_data(r);

	/* write an IPP response back to the network */
	r->content_type = "application/ipp";

#ifndef	APACHE2
	ap_send_http_header(r);
#endif

	status = ipp_write_message(write_data, r, response);
	if (status != PAPI_OK)
		_log_rerror(APLOG_MARK, APLOG_ERR, r,
			"write failed: %s\n", papiStatusString(status));
#ifdef DEBUG
	fprintf(stderr, "write result: %s\n", papiStatusString(status));
	fflush(stderr);
#endif

	papiAttributeListFree(request);
	papiAttributeListFree(response);

#ifndef APACHE2
	ap_kill_timeout(r);
	if (ap_rflush(r) < 0)
		_log_rerror(APLOG_MARK, APLOG_ERR, r,
			"flush failed, response may not have been sent");
#endif

	return (OK);
}