/** * Fetch the request parameters * @param Parrot_PMC i The interpreter * @param request_rec * r The request * @return Parrot_PMC hash **/ Parrot_PMC mod_parrot_request_parameters(Parrot_PMC interp, request_rec * req) { Parrot_PMC hash; /* todo, make this non-nasty. although it works */ hash = mod_parrot_hash_new(interp); mod_parrot_hash_put(interp, hash, "REQUEST_METHOD", (char*)req->method); mod_parrot_hash_put(interp, hash, "REQUEST_URI", req->unparsed_uri); mod_parrot_hash_put(interp, hash, "QUERY_STRING", req->args ? req->args : ""); mod_parrot_hash_put(interp, hash, "HTTP_HOST", (char*)req->hostname); mod_parrot_hash_put(interp, hash, "SCRIPT_NAME", req->filename); mod_parrot_hash_put(interp, hash, "PATH_INFO", req->path_info); mod_parrot_hash_put(interp, hash, "SERVER_NAME", req->server->server_hostname); mod_parrot_hash_put(interp, hash, "SERVER_PROTOCOL", req->protocol); /* Network parameters. This should be simpler, but it isn't. */ mod_parrot_hash_put(interp, hash, "SERVER_ADDR", ipaddr(req->connection->local_addr)); mod_parrot_hash_put(interp, hash, "SERVER_PORT", apr_itoa(req->pool, req->connection->local_addr->port)); mod_parrot_hash_put(interp, hash, "REMOTE_ADDR", ipaddr(req->connection->remote_addr)); mod_parrot_hash_put(interp, hash, "REMOTE_PORT", apr_itoa(req->pool, req->connection->remote_addr->port)); if(req->server->server_admin) /* I don't believe this is ever NULL */ mod_parrot_hash_put(interp, hash, "SERVER_ADMIN", req->server->server_admin); return hash; }
static const char* ignore_common_prefix(apr_pool_t* pool, int n1, int n2) { char* s1 = apr_itoa(pool, n1); char* s2 = apr_itoa(pool, n2); int n, len1, len2; len1 = strlen(s1); len2 = strlen(s2); if (len1 < len2) return s2; n = 0; while (n < len1 && s1[n] == s2[n]) ++n; return s2 + n; }
void util_ldap_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n) { util_compare_node_t *node = (util_compare_node_t *)n; char date_str[APR_CTIME_LEN+1]; char *buf, *cmp_result; apr_ctime(date_str, node->lastcompare); if (node->result == LDAP_COMPARE_TRUE) { cmp_result = "LDAP_COMPARE_TRUE"; } else if (node->result == LDAP_COMPARE_FALSE) { cmp_result = "LDAP_COMPARE_FALSE"; } else { cmp_result = apr_itoa(r->pool, node->result); } buf = apr_psprintf(r->pool, "<tr valign='top'>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "<tr>", node->dn, node->attrib, node->value, date_str, cmp_result); ap_rputs(buf, r); }
static int pass_in_env(request_rec *r, RuntimeScanner *scanner) { if ((scanner->block && !scanner->learning) || scanner->drop) apr_table_set(r->subprocess_env, "defender_action", "block"); for (const auto &match : scanner->matchScores) { apr_table_set(r->subprocess_env, apr_psprintf(r->pool, "defender_%s", match.first.c_str()), apr_itoa(r->pool, match.second)); } return DECLINED; }
const char *UploadItemIO::get_thumb_path(apr_pool_t *pool, const char *thumb_dir_path, apr_size_t item_id) { return get_path(pool, thumb_dir_path, item_id, apr_pstrcat(pool, apr_itoa(pool, static_cast<int>(item_id)), FILE_EXT_SEPARATOR, VIW_THUMBNAIL_EXT, NULL)); }
// This is the method which does all the work handling the uploads. It's only // triggered by the fixup filter if +porter_should_rewrite_body+ returns true. apr_status_t porter_process_upload(request_rec *r) { porter_server_conf *config = (porter_server_conf *) ap_get_module_config(r->server->module_config, &porter_module); // Prepare the apreq objects. apreq_handle_t *req = apreq_handle_apache2(r); const apr_table_t *request_body = apreq_params(req, r->pool); // Create our upload request object, this is fleshed out by the rest of this method porter_upload_request_t *upload_request = porter_create_request(req, r, config); // This happens with malformed requests. apreq_params should never return null // when the content-length is > 0 and it's a multipart request. So just assume // it's broken and return bad request. Otherwise subsequent method calls will // cause a segfault if (request_body == NULL) { PORTER_LOG_REQUEST_ERROR("Invalid request body"); return HTTP_BAD_REQUEST; } // loop over each parameter provided by the user (see porter_each_parameter) apr_table_do(porter_each_parameter, upload_request, request_body, NULL); // If any of the parameter handlers return an error, they save the error code // in the upload_request. So return that same error code. if (upload_request->status != APR_SUCCESS) { return upload_request->status; } // Just because the content type is multipart and the content-length was > 0 doesn't // mean that the user actually uploaded any files. If they didn't, just return success // and let the original body be passed upstream. if (!apr_is_empty_array(upload_request->param_names)) { // Write the parameter names to the X-Uploads header (comma seperated) const char *upload_parameters = apr_array_pstrcat(r->pool, upload_request->param_names, ','); apr_off_t len; apr_table_setn(r->headers_in, HTTP_X_UPLOADS, upload_parameters); // figure out the length of the newly rewritten body and set it in the request // along with the right content type. apr_brigade_length(upload_request->bucket_brigade, 0, &len); apr_table_setn(r->headers_in, "Content-Length", apr_itoa(r->pool, len)); apr_table_setn(r->headers_in, "Content-Type", "application/x-www-form-urlencoded"); // Add our input filter to the filter chain, this allows // us to replace the request body with our own one, and ensure that // gets passed down to the handler. ap_add_input_filter_handle(porter_input_filter_handle, upload_request, r, r->connection); } return APR_SUCCESS; }
const char *UploadItemIO::get_file_path(apr_pool_t *pool, const char *file_dir_path, UploadItem *uitem) { return get_path (pool, file_dir_path, uitem->get_id(), apr_pstrcat(pool, apr_itoa(pool, static_cast<int>(uitem->get_id())), FILE_EXT_SEPARATOR, uitem->get_file_ext(), NULL)); }
int main(int argc,char **argv) { apr_initialize(); apr_pool_t *pool; apr_pool_create(&pool,NULL); char *str=apr_itoa(pool,1141100895); printf("%s\n",str); apr_pool_destroy(pool); apr_terminate(); return 0; }
void util_ldap_compare_node_display(request_rec *r, util_ald_cache_t *cache, void *n) { util_compare_node_t *node = n; char date_str[APR_CTIME_LEN]; char *cmp_result; char *sub_groups_val; char *sub_groups_checked; apr_ctime(date_str, node->lastcompare); if (node->result == LDAP_COMPARE_TRUE) { cmp_result = "LDAP_COMPARE_TRUE"; } else if (node->result == LDAP_COMPARE_FALSE) { cmp_result = "LDAP_COMPARE_FALSE"; } else { cmp_result = apr_itoa(r->pool, node->result); } if (node->subgroupList) { sub_groups_val = "Yes"; } else { sub_groups_val = "No"; } if (node->sgl_processed) { sub_groups_checked = "Yes"; } else { sub_groups_checked = "No"; } ap_rprintf(r, "<tr valign='top'>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "<td nowrap>%s</td>" "</tr>", node->dn, node->attrib, node->value, date_str, cmp_result, sub_groups_val, sub_groups_checked); }
int slayer_server_log_request(slayer_server_log_manager_t *manager, apr_pool_t *mpool, apr_socket_t *conn, const char *request_line, int response_code, int nbytes_sent, apr_int64_t time_toservice) { //generate data char dstring[1024]; apr_int64_t current_time = apr_time_now(); apr_size_t result_size; apr_time_exp_t ltime; apr_time_exp_lt(<ime,current_time); apr_strftime (dstring, &result_size, sizeof(dstring), "%d/%b/%Y:%H:%M:%S %z", <ime ); apr_sockaddr_t *client_addr; char *client_ip; apr_socket_addr_get(&client_addr,0,conn); apr_sockaddr_ip_get(&client_ip,client_addr); if (manager->fhandle) { char *message = apr_pstrcat(mpool,client_ip," - - ","[",dstring,"] \"",request_line,"\" ", apr_itoa(mpool,response_code)," ",apr_itoa(mpool,nbytes_sent), " ",apr_ltoa(mpool,time_toservice), "\n",NULL); slayer_server_log_message(manager,message); } slayer_server_log_add_entry(manager,mpool,client_ip,current_time,request_line,response_code,nbytes_sent,time_toservice); return 0; }
static const char *log_server_port(request_rec *r, char *a) { apr_port_t port; if (*a == '\0' || !strcasecmp(a, "canonical")) { port = r->server->port ? r->server->port : ap_default_port(r); } else if (!strcasecmp(a, "remote")) { port = r->connection->remote_addr->port; } else if (!strcasecmp(a, "local")) { port = r->connection->local_addr->port; } else { /* bogus format */ return a; } return apr_itoa(r->pool, (int)port); }
/* Apache Handle Process and Output */ static int req_meets(lua_State*L ) { request_rec *r = CHECK_REQUEST_OBJECT(1); apr_time_t mtime = luaL_checkint(L, 2); int len = luaL_checkint(L, 3); int status; if (mtime) ap_update_mtime(r, mtime * APR_USEC_PER_SEC); ap_set_last_modified(r); ap_set_etag(r); ap_set_accept_ranges(r); apr_table_setn(r->headers_out, "Content-Length", apr_itoa(r->pool, len)); status = ap_meets_conditions(r); if (status == 0) { lua_pushnil(L); } else lua_pushinteger(L, status); return 1; }
APR_DECLARE(apr_status_t) stomp_write(stomp_connection *connection, stomp_frame *frame, apr_pool_t* pool) { apr_status_t rc; #define CHECK_SUCCESS if( rc!=APR_SUCCESS ) { return rc; } // Write the command. rc = stomp_write_buffer(connection, frame->command, strlen(frame->command)); CHECK_SUCCESS; rc = stomp_write_buffer(connection, "\n", 1); CHECK_SUCCESS; // Write the headers if( frame->headers != NULL ) { apr_hash_index_t *i; const void *key; void *value; for (i = apr_hash_first(NULL, frame->headers); i; i = apr_hash_next(i)) { apr_hash_this(i, &key, NULL, &value); rc = stomp_write_buffer(connection, key, strlen(key)); CHECK_SUCCESS; rc = stomp_write_buffer(connection, ":", 1); CHECK_SUCCESS; rc = stomp_write_buffer(connection, value, strlen(value)); CHECK_SUCCESS; rc = stomp_write_buffer(connection, "\n", 1); CHECK_SUCCESS; } if(frame->body_length >= 0) { apr_pool_t *length_pool; char *length_string; apr_pool_create(&length_pool, pool); rc = stomp_write_buffer(connection, "content-length:", 15); CHECK_SUCCESS; length_string = apr_itoa(length_pool, frame->body_length); rc = stomp_write_buffer(connection, length_string, strlen(length_string)); CHECK_SUCCESS; rc = stomp_write_buffer(connection, "\n", 1); CHECK_SUCCESS; apr_pool_destroy(length_pool); } } rc = stomp_write_buffer(connection, "\n", 1); CHECK_SUCCESS; // Write the body. if( frame->body != NULL ) { int body_length = frame->body_length; if(body_length < 0) body_length = strlen(frame->body); rc = stomp_write_buffer(connection, frame->body, body_length); CHECK_SUCCESS; } rc = stomp_write_buffer(connection, "\0\n", 2); CHECK_SUCCESS; #undef CHECK_SUCCESS return APR_SUCCESS; }
static apr_status_t call_resolver(apr_sockaddr_t **sa, const char *hostname, apr_int32_t family, apr_port_t port, apr_int32_t flags, apr_pool_t *p) { struct addrinfo hints, *ai, *ai_list; apr_sockaddr_t *prev_sa; int error; char *servname = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; #ifdef HAVE_GAI_ADDRCONFIG if (family == APR_UNSPEC) { /* By default, only look up addresses using address types for * which a local interface is configured, i.e. no IPv6 if no * IPv6 interfaces configured. */ hints.ai_flags = AI_ADDRCONFIG; } #endif if(hostname == NULL) { #ifdef AI_PASSIVE /* If hostname is NULL, assume we are trying to bind to all * interfaces. */ hints.ai_flags |= AI_PASSIVE; #endif /* getaddrinfo according to RFC 2553 must have either hostname * or servname non-NULL. */ #ifdef OSF1 /* The Tru64 5.0 getaddrinfo() can only resolve services given * by the name listed in /etc/services; a numeric or unknown * servname gets an EAI_SERVICE error. So just resolve the * appropriate anyaddr and fill in the port later. */ hostname = family == AF_INET6 ? "::" : "0.0.0.0"; servname = NULL; #ifdef AI_NUMERICHOST hints.ai_flags |= AI_NUMERICHOST; #endif #else #ifdef _AIX /* But current AIX getaddrinfo() doesn't like servname = "0"; * the "1" won't hurt since we use the port parameter to fill * in the returned socket addresses later */ if (!port) { servname = "1"; } else #endif /* _AIX */ servname = apr_itoa(p, port); #endif /* OSF1 */ } error = getaddrinfo(hostname, servname, &hints, &ai_list); #ifdef HAVE_GAI_ADDRCONFIG if (error == EAI_BADFLAGS && family == APR_UNSPEC) { /* Retry with no flags if AI_ADDRCONFIG was rejected. */ hints.ai_flags = 0; error = getaddrinfo(hostname, servname, &hints, &ai_list); } #endif if (error) { #ifndef WIN32 if (error == EAI_SYSTEM) { return errno; } else #endif { /* issues with representing this with APR's error scheme: * glibc uses negative values for these numbers, perhaps so * they don't conflict with h_errno values... Tru64 uses * positive values which conflict with h_errno values */ #if defined(NEGATIVE_EAI) error = -error; #endif return error + APR_OS_START_EAIERR; } } prev_sa = NULL; ai = ai_list; while (ai) { /* while more addresses to report */ apr_sockaddr_t *new_sa; /* Ignore anything bogus: getaddrinfo in some old versions of * glibc will return AF_UNIX entries for APR_UNSPEC+AI_PASSIVE * lookups. */ if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) { ai = ai->ai_next; continue; } new_sa = apr_pcalloc(p, sizeof(apr_sockaddr_t)); new_sa->pool = p; memcpy(&new_sa->sa, ai->ai_addr, ai->ai_addrlen); apr_sockaddr_vars_set(new_sa, ai->ai_family, port); if (!prev_sa) { /* first element in new list */ if (hostname) { new_sa->hostname = apr_pstrdup(p, hostname); } *sa = new_sa; } else { new_sa->hostname = prev_sa->hostname; prev_sa->next = new_sa; } prev_sa = new_sa; ai = ai->ai_next; } freeaddrinfo(ai_list); return APR_SUCCESS; }
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); } }
int mod_but_analyze_response_headers(void *result, const char *key, const char *value) { /* This function is called for all HTTP RESPONSE HEADER HTTP/1.1 302 Found Date: Mon, 22 Aug 2005 21:10:45 GMT Set-Cookie: E2=jLllj33EsXhInvgW5KDkMtzB4YcqLy2Eawv1EAbY0K3NGUHczLF1oIrJ7bURyw1; domain=but.ch; path=/; Set-Cookie: TEST=ABC; Set-Cookie: FREECOOKIE=123; Location: /cgi/cgi-bin/printenv?__cookie_try=1 Content-Length: 281 Content-Type: text/html; charset=iso-8859-1 It checks the Set-Cookie headers. */ cookie_res * cr = (cookie_res *) result; request_rec *r = cr->r; apr_rmm_t *cs_rmm = find_cs_rmm(); apr_rmm_off_t *off = find_cs_rmm_off(); mod_but_server_t *config; mod_but_dir_t *dconfig = ap_get_module_config(r->per_dir_config, &but_module); pcre *re; // the regular expression const char *error; // error text for the failed regex compilation int error_offset; // offset of the regex compilation error, if any int rc = 0; // return code of pcre_exec int re_vector[3072]; apr_int64_t num_set_cookie; apr_int64_t auth_strength; char *qa = (char *)apr_pstrdup(r->pool, value); char *p, *last; ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: CALLING OUTPUT FILTER"); config = ap_get_module_config(r->server->module_config, &but_module); if (config == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Illegal server record (output filter)"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Request URI [%s]", r->uri); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Working with SHM offset [%s]", apr_table_get(r->notes, "SHMOFFSET")); re = pcre_compile("cOOkIe", PCRE_CASELESS, &error, &error_offset, NULL); if (re == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: return code of pcre_compile in Cookie Store is NULL"); return DECLINED; } if(key==NULL){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: key is NULL"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } rc = pcre_exec(re, NULL, key, strlen(key), 0, 0, re_vector, 3072); if (rc < 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Set-Cookie was not in ARGS = %s", key); return DECLINED; } if (rc == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: PCRE output vector too small (%d)", 3072/3-1); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Problems with the following ARGS = %s", key); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } if (rc > 0) { char* val1; char* substr; char* key1; mod_but_cookie_cookiestore *csp; apr_rmm_t *cs_rmm_cookiestore; apr_rmm_off_t *off_cookiestore; ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: ====================== FIND SET-COOKIE HEADER ====================="); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Found Set-Cookie [%s]=[%s]", key,value); /* Store Set-Cookie attributes into mod_but_cookie_cookiestore struct */ substr = strchr(value, '=' ); key1 = (char*)apr_pstrndup(r->pool, value, (strlen(value)-strlen(substr)) ); substr++; // now substr points to the value if (strchr(substr,';')) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: OUTPUT_FILTER: COOKIE HAS \";\""); val1 = (char*)apr_pstrndup( r->pool, substr, (strlen(substr)-strlen(strchr(substr,';'))) ); } else { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: OUTPUT_FILTER: COOKIE HAS NO \";\""); val1 = (char*)apr_pstrndup( r->pool, substr, (strlen(substr))); } if (!apr_strnatcmp(key1, "") && !apr_strnatcmp(val1, "")){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unparsed %s - %s", key1, val1); return OK; } csp = apr_palloc(r->pool, sizeof(mod_but_cookie_cookiestore)); apr_cpystrn(csp->cookie_name, key1, sizeof(csp->cookie_name)); apr_cpystrn(csp->cookie_value, val1, sizeof(csp->cookie_value)); if (dconfig == NULL) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_authorization.c: Illegal Directory Config (location_id)"); } csp->location_id = dconfig->mod_but_location_id; // remember the location, for which a cookie was set. ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: COOKIE LOCATION ID [%d]", csp->location_id); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: PARSED COOKIENAME AND VALUE [%s]-[%s]", csp->cookie_name, csp->cookie_value); cs_rmm_cookiestore = find_cs_rmm_cookiestore(); off_cookiestore = find_cs_rmm_off_cookiestore(); if(apr_table_get(r->notes, "SHMOFFSET")){ apr_int64_t i = apr_atoi64(apr_table_get(r->notes, "SHMOFFSET")); mod_but_cookie *c = apr_rmm_addr_get(cs_rmm, off[i]); /* 1) LOGON cookie? 2) SERVICE_LIST cookie? 3) FREE COOKIE? 4) MOD_BUT_SESSION? 5) Others */ /* 1) Lets see, if the cookie is a LOGON cookie */ if (!apr_strnatcmp(csp->cookie_name, config->global_logon_auth_cookie_name)){ /* First, we set the logon flag to true */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: FOUND LOGON Header"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Requesting r->uri is: %s", r->uri); re = pcre_compile(config->authorized_logon_url, PCRE_CASELESS, &error, &error_offset, NULL); rc = pcre_exec(re, NULL, r->uri, strlen(r->uri), 0, 0, re_vector, 3072); if (rc < 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: LOGON=ok from unauthorized source - we denied it"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unsetting LOGON=ok from response header"); return DECLINED; } if (rc == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: PCRE output vector too small (%d)", 3072/3-1); return DECLINED; } if (rc > 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: LOGON comes form a trusted/authorized source"); if (!apr_strnatcmp(csp->cookie_value, config->global_logon_auth_cookie_value)){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: LOGON=ok comes form a trusted/authorized source"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: LOGON=ok (set c->logon_state=1)"); c->logon_state=1; apr_table_set(r->notes, "LOGON_STATUS", "OK"); } // unset LOGON cookie from the response header ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unsetting LOGON=ok from response header"); return DECLINED; } } /* 3) Check if we have a FREE Cookie (configured in httpd.conf) We do not store FREE Cookies into the cookie store */ if(config->session_store_free_cookies){ char *temp; ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: MOD_BUT_SESSION_STORE_FREE_COOKIES is configured"); re = pcre_compile(config->session_store_free_cookies, 0, &error, &error_offset, NULL); if (re == NULL) { // ap_log_rerror(PC_LOG_INFO, } temp = apr_pstrcat(r->pool, key1, "=", value, NULL); rc = pcre_exec(re, NULL, temp, strlen(temp), 0, 0, re_vector, 3072); if (rc < 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Set-Cookie is not a FREE COOKIE key = %s | value = %s", key1, value); } if (rc == 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: PCRE output vector too small (%d)", 3072/3-1); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Problems with the following ARGS = %s", key1); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } if (rc > 0) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: FOUND FREE COOKIE [%s] [%s]", key1, value); num_set_cookie = apr_atoi64(apr_table_get(r->notes, "NUM_SET_COOKIE")); num_set_cookie += 1; apr_table_set(r->notes, "NUM_SET_COOKIE", apr_itoa(r->pool, num_set_cookie)); apr_table_set(r->notes, apr_itoa(r->pool, num_set_cookie), value); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter: VALUE IS [%s]", apr_table_get(r->notes, apr_itoa(r->pool, num_set_cookie))); return DECLINED; } } /* 4) If the Cookie is the MOD_BUT_SESSION, we don't want to have that cookie stored in the cookie store This means, that NO backend application is allowed to have the same cookie name as the MOD_BUT_SESSION */ if (!apr_strnatcmp(key1, config->cookie_name)){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Set-Cookie is MOD_BUT_SESSION"); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; } /* 5) If LOGON=ok, we will store the special meaning cookies in a special way here. */ if (apr_table_get(r->notes, "LOGON_STATUS") != NULL){ if (!apr_strnatcmp(key1, "MOD_BUT_AUTH_STRENGTH")){ auth_strength = apr_atoi64(val1); if ((auth_strength >= 0) || (auth_strength <= 2)) { c->auth_strength=auth_strength; } else { c->auth_strength= 0; // default value, if auth_strength is not parseable or greater than 2 } return DECLINED; } /* Lets see, if the SERVICE_LIST cookie is set */ if (!apr_strnatcmp(csp->cookie_name, config->service_list_cookie_name)){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: FOUND SERVICE LIST Cookiename (Authorization Regex)"); apr_cpystrn(c->service_list, val1, sizeof(c->service_list)); return DECLINED; } if (!apr_strnatcmp(key1, "MOD_BUT_BACKEND_SESSION")){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: FOUND MOD_BUT_BACKEND_SESSION [%s]", value); char *p1 = NULL; char *p2 = NULL; char *p3 = NULL; char *p11 = NULL; char *p21 = NULL; char *p31 = NULL; for(p = (char *)apr_strtok(qa, "; ", &last); p != NULL; p = (char *)apr_strtok(NULL, "; ", &last)) { p1 = strstr(p, "bname"); if(p1){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bname found [%s]", p1); p1 += strlen("bname"); if(*p1 == '=') { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bname [%s]", (char *)apr_pstrdup(r->pool, p1+1)); p11 = apr_pstrdup(r->pool, p1+1); } } p2 = strstr(p, "bvalue"); if(p2){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bvalue [%s]", p2); p2 += strlen("bvalue"); if(*p2 == '=') { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bvalue [%s]", (char *)apr_pstrdup(r->pool, p2+1)); p21 = apr_pstrdup(r->pool, p2+1); } } p3 = strstr(p, "bclearance"); if(p3){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bclearance [%s]", p3); p3 += strlen("bclearance"); if(*p3 == '=') { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bclearance [%s]", (char *)apr_pstrdup(r->pool, p3+1)); p31 = apr_pstrdup(r->pool, p3+1); } } } ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: bname found [%s]=[%s] CLEAR [%s]", p11,p21,p31); for(p31 = apr_strtok(p31, ",", &last); p31 != NULL; p31 = apr_strtok(NULL, ",", &last)) { ap_log_rerror(PC_LOG_INFO, r, "mod_but_request_filter.c: P31 = [%s]", p31); apr_cpystrn(csp->cookie_name, p11, sizeof(csp->cookie_name)); apr_cpystrn(csp->cookie_value, p21, sizeof(csp->cookie_value)); csp->location_id = apr_atoi64(p31); if (c->link_to_cookiestore == -1){ /* Here we have to update the c->link_to_cookiestore */ int cookiestore_offset = find_empty_cookiestore_slot(r); if (cookiestore_offset >= 0){ mod_but_cookie_cookiestore *cs; /* If we are here, we found an empty cookiestore shm storage we can put our stuff into */ cs = apr_rmm_addr_get(cs_rmm_cookiestore, off_cookiestore[cookiestore_offset]); apr_cpystrn(cs->cookie_name, p11, sizeof(cs->cookie_name)); apr_cpystrn(cs->cookie_value, p21, sizeof(cs->cookie_value)); c->link_to_cookiestore = cookiestore_offset; cs->location_id = apr_atoi64(p31); }else{ /* If we are here, we did not have more cookiestore shm */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unable finding new cookiestore slot"); apr_table_set(r->notes, "CS_SHM" , "PROBLEM"); } } else { int status; // if we are here, we are not the first cookie to be saved. status = store_cookie_in_cookiestore(r, c->link_to_cookiestore, csp); if (status == 30){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: All Cookiestore SHM used [%d] - Status", status); apr_table_set(r->notes, "CS_SHM" , "PROBLEM"); } } } /* Loop around clearance and save the cookies into the correct location_id */ return DECLINED; } } /* 6) If the Cookie does not have a special meaning to us, let's store them in the session store (without DLS) */ // store all other cookies to the cookiestore if (c->link_to_cookiestore == -1){ /* Here we have to update the c->link_to_cookiestore */ int cookiestore_offset = find_empty_cookiestore_slot(r); if (cookiestore_offset >= 0){ mod_but_cookie_cookiestore *cs; /* If we are here, we found an empty cookiestore shm storage we can put our stuff into */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: OUTPUT FILTER: ANCHOR LINK TO COOKIE STORE [%d]", cookiestore_offset); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Copy HEADER @ CS offset %d", cookiestore_offset); cs = apr_rmm_addr_get(cs_rmm_cookiestore, off_cookiestore[cookiestore_offset]); apr_cpystrn(cs->cookie_name, key1, sizeof(cs->cookie_name)); apr_cpystrn(cs->cookie_value, val1, sizeof(cs->cookie_value)); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STOREING NEW cookie_name [%s]=[%s] in CookieStore", cs->cookie_name, cs->cookie_value); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STOREING NEW cookie_name [%s] and cookie_value [%s] @ CS offset [%d] and cookie_next is [%d]", cs->cookie_name, cs->cookie_value, cookiestore_offset, cs->cookie_next); c->link_to_cookiestore = cookiestore_offset; cs->location_id = dconfig->mod_but_location_id; ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STOREING NEW cookie_name [%s] = [%s] ", cs->cookie_name, cs->cookie_value); ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STOREING NEW cookie_name [%s] and cookie_value [%s] @ CS offset [%d] and cookie_next is [%d] and cookie_before is [%d]", cs->cookie_name, cs->cookie_value, cookiestore_offset, cs->cookie_next, cs->cookie_before); }else{ /* If we are here, we did not have more cookiestore shm */ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: Unable finding new cookiestore slot"); apr_table_set(r->notes, "CS_SHM" , "PROBLEM"); } } else { int status; // if we are here, we are not the first cookie to be saved. ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: STORE [%s]=[%s]", csp->cookie_name,csp->cookie_value); status = store_cookie_in_cookiestore(r, c->link_to_cookiestore, csp); if (status == 30){ ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: All Cookiestore SHM used [%d] - Status", status); apr_table_set(r->notes, "CS_SHM" , "PROBLEM"); } } } } ap_log_rerror(PC_LOG_INFO, r, "mod_but_output_filter.c: END OF OUTPUT FILTER"); return DECLINED; }
/* 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); }
static const char *log_requests_on_connection(request_rec *r, char *a) { int num = r->connection->keepalives ? r->connection->keepalives - 1 : 0; return apr_itoa(r->pool, num); }
aos_status_t *log_post_logs_with_sts_token(aos_pool_t *p, const char *endpoint, const char * accesskeyId, const char *accessKey, const char *stsToken, const char *project, const char *logstore, cJSON *root) { aos_string_t project_name, logstore_name; aos_table_t *headers = NULL; aos_table_t *resp_headers = NULL; log_request_options_t *options = NULL; aos_list_t buffer; unsigned char *md5 = NULL; char *buf = NULL; int64_t buf_len; char *b64_value = NULL; aos_buf_t *content = NULL; aos_status_t *s = NULL; options = log_request_options_create(p); options->config = log_config_create(options->pool); aos_str_set(&(options->config->endpoint), endpoint); aos_str_set(&(options->config->access_key_id), accesskeyId); aos_str_set(&(options->config->access_key_secret), accessKey); if(stsToken != NULL) { aos_str_set(&(options->config->sts_token), stsToken); } options->ctl = aos_http_controller_create(options->pool, 0); headers = aos_table_make(p, 5); apr_table_set(headers, LOG_API_VERSION, "0.6.0"); apr_table_set(headers, LOG_COMPRESS_TYPE, "lz4"); apr_table_set(headers, LOG_SIGNATURE_METHOD, "hmac-sha1"); apr_table_set(headers, LOG_CONTENT_TYPE, "application/json"); aos_str_set(&project_name, project); aos_str_set(&logstore_name, logstore); aos_list_init(&buffer); char *body = cJSON_PrintUnformatted(root); if(body == NULL) { s = aos_status_create(options->pool); aos_status_set(s, 400, AOS_CLIENT_ERROR_CODE, "fail to format cJSON data"); return s; } int org_body_size = strlen(body); apr_table_set(headers, LOG_BODY_RAW_SIZE, apr_itoa(options->pool, org_body_size)); int compress_bound = LZ4_compressBound(org_body_size); char *compress_data = aos_pcalloc(options->pool, compress_bound); int compressed_size = LZ4_compress(body, compress_data, org_body_size); if(compressed_size <= 0) { s = aos_status_create(options->pool); aos_status_set(s, 400, AOS_CLIENT_ERROR_CODE, "fail to compress json data"); return s; } content = aos_buf_pack(options->pool, compress_data, compressed_size); aos_list_add_tail(&content->node, &buffer); //add Content-MD5 buf_len = aos_buf_list_len(&buffer); buf = aos_buf_list_content(options->pool, &buffer); md5 = aos_md5(options->pool, buf, (apr_size_t)buf_len); b64_value = aos_pcalloc(options->pool, 50); int loop = 0; for(; loop < 16; ++loop) { unsigned char a = ((*md5)>>4) & 0xF, b = (*md5) & 0xF; b64_value[loop<<1] = a > 9 ? (a - 10 + 'A') : (a + '0'); b64_value[(loop<<1)|1] = b > 9 ? (b - 10 + 'A') : (b + '0'); ++md5; } b64_value[loop<<1] = '\0'; apr_table_set(headers, LOG_CONTENT_MD5, b64_value); s = log_post_logs_from_buffer(options, &project_name, &logstore_name, &buffer, headers, &resp_headers); free(body); return s; }
static apr_status_t ajp_marshal_into_msgb(ajp_msg_t *msg, request_rec *r, apr_uri_t *uri) { int method; apr_uint32_t i, num_headers = 0; apr_byte_t is_ssl; char *remote_host; const char *session_route, *envvar; const apr_array_header_t *arr = apr_table_elts(r->subprocess_env); const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts; ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, "Into ajp_marshal_into_msgb"); if ((method = sc_for_req_method_by_id(r)) == UNKNOWN_METHOD) { ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, APLOGNO(02437) "ajp_marshal_into_msgb - Sending unknown method %s as request attribute", r->method); method = SC_M_JK_STORED; } is_ssl = (apr_byte_t) ap_proxy_conn_is_https(r->connection); if (r->headers_in && apr_table_elts(r->headers_in)) { const apr_array_header_t *t = apr_table_elts(r->headers_in); num_headers = t->nelts; } remote_host = (char *)ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_HOST, NULL); ajp_msg_reset(msg); if (ajp_msg_append_uint8(msg, CMD_AJP13_FORWARD_REQUEST) || ajp_msg_append_uint8(msg, (apr_byte_t) method) || ajp_msg_append_string(msg, r->protocol) || ajp_msg_append_string(msg, uri->path) || ajp_msg_append_string(msg, r->useragent_ip) || ajp_msg_append_string(msg, remote_host) || ajp_msg_append_string(msg, ap_get_server_name(r)) || ajp_msg_append_uint16(msg, (apr_uint16_t)r->connection->local_addr->port) || ajp_msg_append_uint8(msg, is_ssl) || ajp_msg_append_uint16(msg, (apr_uint16_t) num_headers)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00968) "ajp_marshal_into_msgb: " "Error appending the message beginning"); return APR_EGENERAL; } for (i = 0 ; i < num_headers ; i++) { int sc; const apr_array_header_t *t = apr_table_elts(r->headers_in); const apr_table_entry_t *elts = (apr_table_entry_t *)t->elts; if ((sc = sc_for_req_header(elts[i].key)) != UNKNOWN_METHOD) { if (ajp_msg_append_uint16(msg, (apr_uint16_t)sc)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00969) "ajp_marshal_into_msgb: " "Error appending the header name"); return AJP_EOVERFLOW; } } else { if (ajp_msg_append_string(msg, elts[i].key)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00970) "ajp_marshal_into_msgb: " "Error appending the header name"); return AJP_EOVERFLOW; } } if (ajp_msg_append_string(msg, elts[i].val)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00971) "ajp_marshal_into_msgb: " "Error appending the header value"); return AJP_EOVERFLOW; } ap_log_rerror(APLOG_MARK, APLOG_TRACE5, 0, r, "ajp_marshal_into_msgb: Header[%d] [%s] = [%s]", i, elts[i].key, elts[i].val); } /* XXXX need to figure out how to do this if (s->secret) { if (ajp_msg_append_uint8(msg, SC_A_SECRET) || ajp_msg_append_string(msg, s->secret)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Error ajp_marshal_into_msgb - " "Error appending secret"); return APR_EGENERAL; } } */ if (r->user) { if (ajp_msg_append_uint8(msg, SC_A_REMOTE_USER) || ajp_msg_append_string(msg, r->user)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00972) "ajp_marshal_into_msgb: " "Error appending the remote user"); return AJP_EOVERFLOW; } } if (r->ap_auth_type) { if (ajp_msg_append_uint8(msg, SC_A_AUTH_TYPE) || ajp_msg_append_string(msg, r->ap_auth_type)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00973) "ajp_marshal_into_msgb: " "Error appending the auth type"); return AJP_EOVERFLOW; } } /* XXXX ebcdic (args converted?) */ if (uri->query) { if (ajp_msg_append_uint8(msg, SC_A_QUERY_STRING) || ajp_msg_append_string(msg, uri->query)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00974) "ajp_marshal_into_msgb: " "Error appending the query string"); return AJP_EOVERFLOW; } } if ((session_route = apr_table_get(r->notes, "session-route"))) { if (ajp_msg_append_uint8(msg, SC_A_JVM_ROUTE) || ajp_msg_append_string(msg, session_route)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00975) "ajp_marshal_into_msgb: " "Error appending the jvm route"); return AJP_EOVERFLOW; } } /* XXX: Is the subprocess_env a right place? * <Location /examples> * ProxyPass ajp://remote:8009/servlets-examples * SetEnv SSL_SESSION_ID CUSTOM_SSL_SESSION_ID * </Location> */ /* * Only lookup SSL variables if we are currently running HTTPS. * Furthermore ensure that only variables get set in the AJP message * that are not NULL and not empty. */ if (is_ssl) { if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r, AJP13_SSL_CLIENT_CERT_INDICATOR)) && envvar[0]) { if (ajp_msg_append_uint8(msg, SC_A_SSL_CERT) || ajp_msg_append_string(msg, envvar)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00976) "ajp_marshal_into_msgb: " "Error appending the SSL certificates"); return AJP_EOVERFLOW; } } if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r, AJP13_SSL_CIPHER_INDICATOR)) && envvar[0]) { if (ajp_msg_append_uint8(msg, SC_A_SSL_CIPHER) || ajp_msg_append_string(msg, envvar)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00977) "ajp_marshal_into_msgb: " "Error appending the SSL ciphers"); return AJP_EOVERFLOW; } } if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r, AJP13_SSL_SESSION_INDICATOR)) && envvar[0]) { if (ajp_msg_append_uint8(msg, SC_A_SSL_SESSION) || ajp_msg_append_string(msg, envvar)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00978) "ajp_marshal_into_msgb: " "Error appending the SSL session"); return AJP_EOVERFLOW; } } /* ssl_key_size is required by Servlet 2.3 API */ if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r, AJP13_SSL_KEY_SIZE_INDICATOR)) && envvar[0]) { if (ajp_msg_append_uint8(msg, SC_A_SSL_KEY_SIZE) || ajp_msg_append_uint16(msg, (unsigned short) atoi(envvar))) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00979) "ajp_marshal_into_msgb: " "Error appending the SSL key size"); return APR_EGENERAL; } } } /* If the method was unrecognized, encode it as an attribute */ if (method == SC_M_JK_STORED) { if (ajp_msg_append_uint8(msg, SC_A_STORED_METHOD) || ajp_msg_append_string(msg, r->method)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02438) "ajp_marshal_into_msgb: " "Error appending the method '%s' as request attribute", r->method); return AJP_EOVERFLOW; } } /* Forward the remote port information, which was forgotten * from the builtin data of the AJP 13 protocol. * Since the servlet spec allows to retrieve it via getRemotePort(), * we provide the port to the Tomcat connector as a request * attribute. Modern Tomcat versions know how to retrieve * the remote port from this attribute. */ { const char *key = SC_A_REQ_REMOTE_PORT; char *val = apr_itoa(r->pool, r->useragent_addr->port); if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) || ajp_msg_append_string(msg, key) || ajp_msg_append_string(msg, val)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00980) "ajp_marshal_into_msgb: " "Error appending attribute %s=%s", key, val); return AJP_EOVERFLOW; } } /* Forward the local ip address information, which was forgotten * from the builtin data of the AJP 13 protocol. * Since the servlet spec allows to retrieve it via getLocalAddr(), * we provide the address to the Tomcat connector as a request * attribute. Modern Tomcat versions know how to retrieve * the local address from this attribute. */ { const char *key = SC_A_REQ_LOCAL_ADDR; char *val = r->connection->local_ip; if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) || ajp_msg_append_string(msg, key) || ajp_msg_append_string(msg, val)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02646) "ajp_marshal_into_msgb: " "Error appending attribute %s=%s", key, val); return AJP_EOVERFLOW; } } /* Use the environment vars prefixed with AJP_ * and pass it to the header striping that prefix. */ for (i = 0; i < (apr_uint32_t)arr->nelts; i++) { if (!strncmp(elts[i].key, "AJP_", 4)) { if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) || ajp_msg_append_string(msg, elts[i].key + 4) || ajp_msg_append_string(msg, elts[i].val)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00981) "ajp_marshal_into_msgb: " "Error appending attribute %s=%s", elts[i].key, elts[i].val); return AJP_EOVERFLOW; } } } if (ajp_msg_append_uint8(msg, SC_A_ARE_DONE)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00982) "ajp_marshal_into_msgb: " "Error appending the message end"); return AJP_EOVERFLOW; } ap_log_rerror(APLOG_MARK, APLOG_TRACE8, 0, r, "ajp_marshal_into_msgb: Done"); return APR_SUCCESS; }
/****************************************************************************** * protected メソッド *****************************************************************************/ const char *UploadItemIO::get_data_path(apr_pool_t *pool, apr_size_t item_id) const { return get_path(pool, data_dir_path_, item_id, apr_itoa(pool, static_cast<int>(item_id))); }
static apr_status_t test_rmm(apr_pool_t *parpool) { apr_status_t rv; apr_pool_t *pool; apr_shm_t *shm; apr_rmm_t *rmm; apr_size_t size, fragsize; apr_rmm_off_t *off; int i; void *entity; rv = apr_pool_create(&pool, parpool); if (rv != APR_SUCCESS) { fprintf(stderr, "Error creating child pool\n"); return rv; } /* We're going to want 10 blocks of data from our target rmm. */ size = SHARED_SIZE + apr_rmm_overhead_get(FRAG_COUNT + 1); printf("Creating anonymous shared memory (%" APR_SIZE_T_FMT " bytes).....", size); rv = apr_shm_create(&shm, size, NULL, pool); if (rv != APR_SUCCESS) { fprintf(stderr, "Error allocating shared memory block\n"); return rv; } fprintf(stdout, "OK\n"); printf("Creating rmm segment............................."); rv = apr_rmm_init(&rmm, NULL, apr_shm_baseaddr_get(shm), size, pool); if (rv != APR_SUCCESS) { fprintf(stderr, "Error allocating rmm..............\n"); return rv; } fprintf(stdout, "OK\n"); fragsize = SHARED_SIZE / FRAG_COUNT; printf("Creating each fragment of size %" APR_SIZE_T_FMT "................", fragsize); off = apr_palloc(pool, FRAG_COUNT * sizeof(apr_rmm_off_t)); for (i = 0; i < FRAG_COUNT; i++) { off[i] = apr_rmm_malloc(rmm, fragsize); } fprintf(stdout, "OK\n"); printf("Checking for out of memory allocation............"); if (apr_rmm_malloc(rmm, FRAG_SIZE * FRAG_COUNT) == 0) { fprintf(stdout, "OK\n"); } else { return APR_EGENERAL; } printf("Checking each fragment for address alignment....."); for (i = 0; i < FRAG_COUNT; i++) { char *c = apr_rmm_addr_get(rmm, off[i]); apr_size_t sc = (apr_size_t)c; if (off[i] == 0) { printf("allocation failed for offset %d\n", i); return APR_ENOMEM; } if (sc & 7) { printf("Bad alignment for fragment %d; %p not %p!\n", i, c, (void *)APR_ALIGN_DEFAULT((apr_size_t)c)); return APR_EGENERAL; } } fprintf(stdout, "OK\n"); printf("Setting each fragment to a unique value.........."); for (i = 0; i < FRAG_COUNT; i++) { int j; char **c = apr_rmm_addr_get(rmm, off[i]); for (j = 0; j < FRAG_SIZE; j++, c++) { *c = apr_itoa(pool, i + j); } } fprintf(stdout, "OK\n"); printf("Checking each fragment for its unique value......"); for (i = 0; i < FRAG_COUNT; i++) { int j; char **c = apr_rmm_addr_get(rmm, off[i]); for (j = 0; j < FRAG_SIZE; j++, c++) { char *d = apr_itoa(pool, i + j); if (strcmp(*c, d) != 0) { return APR_EGENERAL; } } } fprintf(stdout, "OK\n"); printf("Freeing each fragment............................"); for (i = 0; i < FRAG_COUNT; i++) { rv = apr_rmm_free(rmm, off[i]); if (rv != APR_SUCCESS) { return rv; } } fprintf(stdout, "OK\n"); printf("Creating one large segment......................."); off[0] = apr_rmm_calloc(rmm, SHARED_SIZE); fprintf(stdout, "OK\n"); printf("Setting large segment............................"); for (i = 0; i < FRAG_COUNT * FRAG_SIZE; i++) { char **c = apr_rmm_addr_get(rmm, off[0]); c[i] = apr_itoa(pool, i); } fprintf(stdout, "OK\n"); printf("Freeing large segment............................"); apr_rmm_free(rmm, off[0]); fprintf(stdout, "OK\n"); printf("Creating each fragment of size %" APR_SIZE_T_FMT " (again)........", fragsize); for (i = 0; i < FRAG_COUNT; i++) { off[i] = apr_rmm_malloc(rmm, fragsize); } fprintf(stdout, "OK\n"); printf("Freeing each fragment backwards.................."); for (i = FRAG_COUNT - 1; i >= 0; i--) { rv = apr_rmm_free(rmm, off[i]); if (rv != APR_SUCCESS) { return rv; } } fprintf(stdout, "OK\n"); printf("Creating one large segment (again)..............."); off[0] = apr_rmm_calloc(rmm, SHARED_SIZE); fprintf(stdout, "OK\n"); printf("Freeing large segment............................"); apr_rmm_free(rmm, off[0]); fprintf(stdout, "OK\n"); printf("Checking realloc................................."); off[0] = apr_rmm_calloc(rmm, SHARED_SIZE - 100); off[1] = apr_rmm_calloc(rmm, 100); if (off[0] == 0 || off[1] == 0) { printf("FAILED\n"); return APR_EINVAL; } entity = apr_rmm_addr_get(rmm, off[1]); rv = apr_rmm_free(rmm, off[0]); if (rv != APR_SUCCESS) { printf("FAILED\n"); return rv; } { unsigned char *c = entity; /* Fill in the region; the first half with zereos, which will * likely catch the apr_rmm_realloc offset calculation bug by * making it think the old region was zero length. */ for (i = 0; i < 100; i++) { c[i] = (i < 50) ? 0 : i; } } /* now we can realloc off[1] and get many more bytes */ off[0] = apr_rmm_realloc(rmm, entity, SHARED_SIZE - 100); if (off[0] == 0) { printf("FAILED\n"); return APR_EINVAL; } { unsigned char *c = apr_rmm_addr_get(rmm, off[0]); /* fill in the region */ for (i = 0; i < 100; i++) { if (c[i] != (i < 50 ? 0 : i)) { printf("FAILED at offset %d: %hx\n", i, c[i]); return APR_EGENERAL; } } } fprintf(stdout, "OK\n"); printf("Destroying rmm segment..........................."); rv = apr_rmm_destroy(rmm); if (rv != APR_SUCCESS) { printf("FAILED\n"); return rv; } printf("OK\n"); printf("Destroying shared memory segment................."); rv = apr_shm_destroy(shm); if (rv != APR_SUCCESS) { printf("FAILED\n"); return rv; } printf("OK\n"); apr_pool_destroy(pool); return APR_SUCCESS; }
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); } }
static char *format_integer(apr_pool_t *p, int i) { return apr_itoa(p, i); }
/** * The output filter routine. This one gets called whenever a response is * generated that passes this filter. Returns APR_SUCCESS if everything works * out. * * @param f The filter definition. * @param bb The bucket brigade containing the data. */ static apr_status_t replace_output_filter(ap_filter_t *f, apr_bucket_brigade *bb) { request_rec *r = f->r; conn_rec *c = r->connection; replace_ctx_t *ctx = f->ctx; apr_bucket *b; apr_size_t len; const char *data; const char *header; apr_status_t rv; int re_vector[RE_VECTOR_SIZE]; // 3 elements per matched pattern replace_pattern_t *next; header_replace_pattern_t *next_header; int modified = 0; // flag to determine if a replacement has // occured. if (!ctx) { /* Initialize context */ ctx = apr_pcalloc(f->r->pool, sizeof(replace_ctx_t)); f->ctx = ctx; ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc); } /* parse config settings */ /* look for the user-defined filter */ ctx->filter = find_filter_def(f->r->server, f->frec->name); if (!ctx->filter) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r, "couldn't find definition of filter '%s'", f->frec->name); return APR_EINVAL; } ctx->p = f->r->pool; if (ctx->filter->intype && ctx->filter->intype != INTYPE_ALL) { if (!f->r->content_type) { ctx->noop = 1; } else { const char *ctypes = f->r->content_type; const char *ctype = ap_getword(f->r->pool, &ctypes, ';'); if (strcasecmp(ctx->filter->intype, ctype)) { /* wrong IMT for us; don't mess with the output */ ctx->noop = 1; } } } /* exit immediately if there are indications that the filter shouldn't be * executed. */ if (ctx->noop == 1) { ap_pass_brigade(f->next, bb); return APR_SUCCESS; } /** * Loop through the configured header patterns. */ for (next_header = ctx->filter->header_pattern; next_header != NULL; next_header = next_header->next) { // create a separate table with the requested HTTP header entries and // unset those headers in the original request. apr_table_t *header_table; header_table = apr_table_make(r->pool, 2); // create a data structure for the callback function header_replace_cb_t *hrcb; hrcb = apr_palloc(r->pool, sizeof(header_replace_cb_t)); hrcb->header_table = header_table; hrcb->pattern = next_header->pattern; hrcb->extra = next_header->extra; hrcb->replacement = next_header->replacement; hrcb->r = r; // pass any header that is defined to be processed to the callback // function and unset those headers in the original outgoing record. apr_table_do(replace_header_cb, hrcb, r->headers_out, next_header->header, NULL); // only touch the header if the changed header table is not empty. if (!apr_is_empty_table(header_table)) { apr_table_unset(r->headers_out, next_header->header); // overlay the original header table with the new one to reintegrate // the changed headers. r->headers_out = apr_table_overlay(r->pool, r->headers_out, header_table); } } /* Not nice but neccessary: Unset the ETag , because we cannot adjust the * value correctly, because we do not know how. */ apr_table_unset(f->r->headers_out, "ETag"); int eos = 0; // flag to check if an EOS bucket is in the brigade. apr_bucket *eos_bucket; // Backup for the EOS bucket. /* Interate through the available data. Stop if there is an EOS */ for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) { if (APR_BUCKET_IS_EOS(b)) { eos = 1; ap_save_brigade(f, &ctx->bb, &bb, ctx->p); APR_BUCKET_REMOVE(b); eos_bucket = b; break; } } /* If the iteration over the brigade hasn't found an EOS bucket, just save * the brigade and return. */ if (eos != 1) { ap_save_brigade(f, &ctx->bb, &bb, ctx->p); return APR_SUCCESS; } if ((rv = apr_brigade_pflatten(ctx->bb, (char **)&data, &len, ctx->p)) != APR_SUCCESS) { /* Return if the flattening didn't work. */ return rv; } else { /* Remove the original data from the bucket brigade. Otherwise it would * be passed twice (original data and the processed, flattened copy) to * the next filter. */ apr_brigade_cleanup(ctx->bb); } /* Good cast, we just tested len isn't negative or zero */ if (len > 0) { /* start checking for the regex's. */ for (next = ctx->filter->pattern; next != NULL; next = next->next) { int rc = 0; int offset = 0; /* loop through the configured patterns */ do { rc = pcre_exec(next->pattern, next->extra, data, len, offset, 0, re_vector, RE_VECTOR_SIZE); if (rc < 0 && rc != PCRE_ERROR_NOMATCH) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "Matching Error %d", rc); return rc; } /* This shouldn´t happen */ if (rc == 0) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "PCRE output vector too small (%d)", RE_VECTOR_SIZE/3-1); } /* If the result count is greater than 0 then there are * matches in the data string. Thus we try to replace those * strings with the user provided string. */ if (rc > 0) { char *prefix; // the string before the matching part. char *postfix; // the string after the matching part. char *newdata; // the concatenated string of prefix, // the replaced string and postfix. char *replacement; // the string with the data to replace // (after the subpattern processing has // been done). char *to_replace[10]; // the string array containing the // strings that are to be replaced. int match_diff; // the difference between the matching // string and its replacement. int x; // a simple counter. char *pos; // the starting position within the // replacement string, where there is a // subpattern to replace. /* start with building the replacement string */ replacement = apr_pstrcat(ctx->p, next->replacement, NULL); /* look for the subpatterns \0 to \9 */ for (x = 0; x < rc && x < 10; x++) { /* extract the x'ths subpattern */ to_replace[x] = substr(data, re_vector[x*2], re_vector[x*2+1] - re_vector[x*2], r); ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "Found match: %s", to_replace[x]); /* the token ( \0 to \9) we are looking for */ char *token = apr_pstrcat(ctx->p, "\\", apr_itoa(ctx->p, x), NULL); /* allocate memory for the replacement operation */ char *tmp; if (!to_replace[x] || strlen(to_replace[x]) < 2) { tmp = malloc(strlen(replacement) + 1); } else { tmp = malloc(strlen(replacement) - 1 + strlen(to_replace[x])); } /* copy the replacement string to the new * location. */ memcpy(tmp, replacement, strlen(replacement) + 1); replacement = tmp; /* try to replace each occurence of the token with * its matched subpattern. */ pos = ap_strstr(replacement, token); while (pos) { if (!to_replace[x]) { break; } substr_replace(pos, to_replace[x], strlen(pos), strlen(to_replace[x])); if (strlen(to_replace[x]) < 2) { tmp = malloc(strlen(replacement) + 1); } else { tmp = malloc(strlen(replacement) - 1 + strlen(to_replace[x])); } memcpy(tmp, replacement, strlen(replacement) + 1); /* clean up. */ free(replacement); replacement = tmp; pos = ap_strstr(replacement, token); } } match_diff = strlen(replacement) - (re_vector[1] - re_vector[0]); /* Allocate memory for a buffer to copy the first part * of the data string up to (but not including) the * the matching pattern. */ prefix = apr_pcalloc(ctx->p, re_vector[0] + 1); if (prefix == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Unable to allocate memory for prefix", NULL); return -1; } /* Copy the string from the offset (beginning of * pattern matching) to the first occurence of the * pattern and add a trailing \0. */ memcpy(prefix, data, (size_t)re_vector[0]); /* Copy the string from the end of the pattern to the * end of the data string itself. */ postfix = apr_pcalloc(ctx->p, len); if (postfix == NULL) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "Unable to allocate memory for postfix", NULL); return -1; } memcpy(postfix, (data + re_vector[1]), len - re_vector[1]); /* Create the new data string, replace the old one * and clean up. */ newdata = apr_pstrcat(ctx->p, prefix, replacement, postfix, NULL); /* update the point of the data and free the allocated * memory for the replacement string. */ data = newdata; free(replacement); /* Calculate the new offset in the data string, where * the new matching round is to begin. */ offset = re_vector[1] + match_diff; len += match_diff; modified = 1; } } while (rc > 0); } /* Adjust the real length of the processed data. */ if (apr_table_get(f->r->headers_out, "Content-Length") != NULL) { apr_table_set(f->r->headers_out, "Content-Length", apr_itoa(ctx->p, len)); } /* If an Entity Tag is set, change the mtime and generate a new ETag.*/ if (apr_table_get(f->r->headers_out, "ETag") != NULL) { r->mtime = time(NULL); ap_set_etag(r); } } /* Create a new bucket with the processed data, insert that one into our * brigade, then insert the saved EOS bucket at the end of the brigade * and pass the brigade to the next filter. */ APR_BRIGADE_INSERT_TAIL(ctx->bb, apr_bucket_transient_create(data, len, apr_bucket_alloc_create(ctx->p))); APR_BRIGADE_INSERT_TAIL(ctx->bb, eos_bucket); ap_pass_brigade(f->next, ctx->bb); return APR_SUCCESS; }
static void test_rmm(abts_case *tc, void *data) { apr_status_t rv; apr_pool_t *pool; apr_shm_t *shm; apr_rmm_t *rmm; apr_size_t size, fragsize; apr_rmm_off_t *off, off2; int i; void *entity; rv = apr_pool_create(&pool, p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* We're going to want 10 blocks of data from our target rmm. */ size = SHARED_SIZE + apr_rmm_overhead_get(FRAG_COUNT + 1); rv = apr_shm_create(&shm, size, NULL, pool); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); if (rv != APR_SUCCESS) return; rv = apr_rmm_init(&rmm, NULL, apr_shm_baseaddr_get(shm), size, pool); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); if (rv != APR_SUCCESS) return; /* Creating each fragment of size fragsize */ fragsize = SHARED_SIZE / FRAG_COUNT; off = apr_palloc(pool, FRAG_COUNT * sizeof(apr_rmm_off_t)); for (i = 0; i < FRAG_COUNT; i++) { off[i] = apr_rmm_malloc(rmm, fragsize); } /* Checking for out of memory allocation */ off2 = apr_rmm_malloc(rmm, FRAG_SIZE * FRAG_COUNT); ABTS_TRUE(tc, !off2); /* Checking each fragment for address alignment */ for (i = 0; i < FRAG_COUNT; i++) { char *c = apr_rmm_addr_get(rmm, off[i]); apr_size_t sc = (apr_size_t)c; ABTS_TRUE(tc, !!off[i]); ABTS_TRUE(tc, !(sc & 7)); } /* Setting each fragment to a unique value */ for (i = 0; i < FRAG_COUNT; i++) { int j; char **c = apr_rmm_addr_get(rmm, off[i]); for (j = 0; j < FRAG_SIZE; j++, c++) { *c = apr_itoa(pool, i + j); } } /* Checking each fragment for its unique value */ for (i = 0; i < FRAG_COUNT; i++) { int j; char **c = apr_rmm_addr_get(rmm, off[i]); for (j = 0; j < FRAG_SIZE; j++, c++) { char *d = apr_itoa(pool, i + j); ABTS_STR_EQUAL(tc, d, *c); } } /* Freeing each fragment */ for (i = 0; i < FRAG_COUNT; i++) { rv = apr_rmm_free(rmm, off[i]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } /* Creating one large segment */ off[0] = apr_rmm_calloc(rmm, SHARED_SIZE); /* Setting large segment */ for (i = 0; i < FRAG_COUNT * FRAG_SIZE; i++) { char **c = apr_rmm_addr_get(rmm, off[0]); c[i] = apr_itoa(pool, i); } /* Freeing large segment */ rv = apr_rmm_free(rmm, off[0]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* Creating each fragment of size fragsize */ for (i = 0; i < FRAG_COUNT; i++) { off[i] = apr_rmm_malloc(rmm, fragsize); } /* Freeing each fragment backwards */ for (i = FRAG_COUNT - 1; i >= 0; i--) { rv = apr_rmm_free(rmm, off[i]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } /* Creating one large segment (again) */ off[0] = apr_rmm_calloc(rmm, SHARED_SIZE); /* Freeing large segment */ rv = apr_rmm_free(rmm, off[0]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); /* Checking realloc */ off[0] = apr_rmm_calloc(rmm, SHARED_SIZE - 100); off[1] = apr_rmm_calloc(rmm, 100); ABTS_TRUE(tc, !!off[0]); ABTS_TRUE(tc, !!off[1]); entity = apr_rmm_addr_get(rmm, off[1]); rv = apr_rmm_free(rmm, off[0]); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); { unsigned char *c = entity; /* Fill in the region; the first half with zereos, which will * likely catch the apr_rmm_realloc offset calculation bug by * making it think the old region was zero length. */ for (i = 0; i < 100; i++) { c[i] = (i < 50) ? 0 : i; } } /* now we can realloc off[1] and get many more bytes */ off[0] = apr_rmm_realloc(rmm, entity, SHARED_SIZE - 100); ABTS_TRUE(tc, !!off[0]); { unsigned char *c = apr_rmm_addr_get(rmm, off[0]); /* fill in the region */ for (i = 0; i < 100; i++) { ABTS_TRUE(tc, c[i] == (i < 50 ? 0 : i)); } } rv = apr_rmm_destroy(rmm); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); rv = apr_shm_destroy(shm); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); apr_pool_destroy(pool); }
static void dbd_pgsql_bbind(apr_pool_t *pool, apr_dbd_prepared_t * statement, const void **values, const char **val, int *len, int *fmt) { int i, j; apr_dbd_type_e type; for (i = 0, j = 0; i < statement->nargs; i++, j++) { type = (values[j] == NULL ? APR_DBD_TYPE_NULL : statement->types[i]); switch (type) { case APR_DBD_TYPE_TINY: val[i] = apr_itoa(pool, *(char*)values[j]); break; case APR_DBD_TYPE_UTINY: val[i] = apr_itoa(pool, *(unsigned char*)values[j]); break; case APR_DBD_TYPE_SHORT: val[i] = apr_itoa(pool, *(short*)values[j]); break; case APR_DBD_TYPE_USHORT: val[i] = apr_itoa(pool, *(unsigned short*)values[j]); break; case APR_DBD_TYPE_INT: val[i] = apr_itoa(pool, *(int*)values[j]); break; case APR_DBD_TYPE_UINT: val[i] = apr_itoa(pool, *(unsigned int*)values[j]); break; case APR_DBD_TYPE_LONG: val[i] = apr_ltoa(pool, *(long*)values[j]); break; case APR_DBD_TYPE_ULONG: val[i] = apr_ltoa(pool, *(unsigned long*)values[j]); break; case APR_DBD_TYPE_LONGLONG: val[i] = apr_psprintf(pool, "%" APR_INT64_T_FMT, *(apr_int64_t*)values[j]); break; case APR_DBD_TYPE_ULONGLONG: val[i] = apr_psprintf(pool, "%" APR_UINT64_T_FMT, *(apr_uint64_t*)values[j]); break; case APR_DBD_TYPE_FLOAT: val[i] = apr_psprintf(pool, "%f", *(float*)values[j]); break; case APR_DBD_TYPE_DOUBLE: val[i] = apr_psprintf(pool, "%lf", *(double*)values[j]); break; case APR_DBD_TYPE_STRING: case APR_DBD_TYPE_TEXT: case APR_DBD_TYPE_TIME: case APR_DBD_TYPE_DATE: case APR_DBD_TYPE_DATETIME: case APR_DBD_TYPE_TIMESTAMP: case APR_DBD_TYPE_ZTIMESTAMP: val[i] = values[j]; break; case APR_DBD_TYPE_BLOB: case APR_DBD_TYPE_CLOB: val[i] = (char*)values[j]; len[i] = *(apr_size_t*)values[++j]; fmt[i] = 1; /* skip table and column */ j += 2; break; case APR_DBD_TYPE_NULL: default: val[i] = NULL; break; } } return; }
/* * Apache output filter. Return values: * HTTP_* HTTP status code for errors * ap_pass_brigade() to pass request down the filter chain * * 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 but_output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) { request_rec *r = f->r; mod_but_server_t *config; session_t session; cookie_res *cr; apr_status_t status; config = ap_get_module_config(r->server->module_config, &but_module); if (config == NULL) { ERRLOG_CRIT("Could not get configuration from apache"); return HTTP_INTERNAL_SERVER_ERROR; } if (!config->enabled) { return ap_pass_brigade(f->next, bb_in); } if (apr_global_mutex_lock(but_mutex) != APR_SUCCESS) { ERRLOG_CRIT("Could not acquire mutex."); return HTTP_INTERNAL_SERVER_ERROR; } but_session_init(&session, r, config); /* get session from request notes */ { const char *indexstr = apr_table_get(r->notes, "BUTSESS"); if (indexstr) { /*OPEN*/ if (but_session_open(&session, atoi(indexstr)) != STATUS_OK) { apr_global_mutex_unlock(but_mutex); ERRLOG_CRIT("Session not found!"); return HTTP_INTERNAL_SERVER_ERROR; /* XXX this may happen in some race conditions. Handle gracefully. */ } } } /* * If no session was found for this response, then this is a free URL and * we have no way to store cookies. Skip cookie filtering. */ if (!but_session_isnull(&session)) { /* * Do Header Parsing for all Set-Cookie Response Headers. We are looking for * a) Session cookie * b) Free cookies * c) Service list cookies * d) Other cookies */ cr = apr_pcalloc(r->pool, sizeof(cookie_res)); if (!cr) { apr_global_mutex_unlock(but_mutex); ERRLOG_CRIT("Out of memory!"); return HTTP_INTERNAL_SERVER_ERROR; } cr->r = r; cr->session = &session; cr->status = STATUS_OK; cr->headers = apr_table_make(r->pool, 0); /*SET*/ apr_table_do(mod_but_filter_response_cookies_cb, cr, r->headers_out, "Set-Cookie", NULL); if (cr->status != STATUS_OK) { if (cr->status == STATUS_ESHMFULL) { status = mod_but_redirect_to_shm_error(r, config); apr_global_mutex_unlock(but_mutex); return status; } ERRLOG_CRIT("Error filtering the response cookies!"); apr_global_mutex_unlock(but_mutex); return HTTP_INTERNAL_SERVER_ERROR; } /* Remove all Set-Cookie headers from response. */ apr_table_unset(r->headers_out, "Set-Cookie"); apr_table_unset(r->err_headers_out, "Set-Cookie"); /* Add selected Set-Cookie headers back into r->headers_out. */ apr_table_do(but_add_to_headers_out_cb, r, cr->headers, NULL); /* * If iteration detected a valid LOGON=ok Set-Cookie header, cr->must_renew is set. */ if (cr->must_renew) { const char *session_handle_str; apr_status_t status; ERRLOG_INFO("=============================== START RENEW SESSION ===================================="); ERRLOG_INFO("Renewing session after login."); /*RENEW*/ status = but_session_renew(&session); if (status != STATUS_OK) { if (status == STATUS_ESHMFULL) { status = mod_but_redirect_to_shm_error(r, config); apr_global_mutex_unlock(but_mutex); return status; } apr_global_mutex_unlock(but_mutex); ERRLOG_INFO("Error renewing session"); return HTTP_INTERNAL_SERVER_ERROR; } if (but_add_session_cookie_to_headers(r, config, r->headers_out, &session) != STATUS_OK) { apr_global_mutex_unlock(but_mutex); return HTTP_INTERNAL_SERVER_ERROR; } /* * renew_mod_but_session returned the new session index we have to update in r->notes. */ session_handle_str = apr_itoa(r->pool, session.handle); if (!session_handle_str) { apr_global_mutex_unlock(but_mutex); ERRLOG_CRIT("Out of memory!"); return HTTP_INTERNAL_SERVER_ERROR; } apr_table_set(r->notes, "BUTSESS", session_handle_str); // REDIRECT TO MOD_BUT_REDIRECT IF ORIG_URL HANDLING IS DISABLED if (!config->but_config_enabled_return_to_orig_url) { ERRLOG_INFO("REDIRECT TO ORIG URL IS DISABLED: REDIRECT TO MOD_BUT_REDIRECT [%s]", session.data->url); ERRLOG_INFO("Redirect to MOD_BUT_REDIRECT if LOGON=ok"); r->status = mod_but_redirect_to_relurl(r, session.data->redirect_url_after_login); } } /* must renew */ } /* have session */ apr_global_mutex_unlock(but_mutex); ap_remove_output_filter(f); return ap_pass_brigade(f->next, bb_in); }
int init_dir_sync(music_globals_t* music_globals){ int status = 0; apr_status_t rv = 0; int i = 0; db_query_t* db_query; db_config_t* db_config; char dbd_error_message[255]; const char* dbd_error; apr_thread_t* thread_sync_dir; #ifdef WITH_MP3 //Init MP3 support mpg123_init(); #endif //Find db_params by finding a query we need and connecting to the database that query depends on status = indexer_get_db_object (file_indexer, "song_id", &(file_db_obj)); if(status != 0){ return -9; } //For every music directory create a shared struct for(i = 0; i < music_globals->music_dirs->nelts; i++){ dir_sh_stats_t* stats; dir_t* dir = &(((dir_t*)music_globals->music_dirs->elts)[i]); dir_sync_thread_t* dir_sync_thread = apr_pcalloc(music_globals->pool, sizeof(dir_sync_thread_t)); //Setup dir_sync_thread dir_sync_thread->db_config = db_config; dir_sync_thread->pool = music_globals->pool; dir_sync_thread->error_messages = music_globals->error_messages; dir_sync_thread->dir = dir; //Setup Dir dir->shm_file = apr_pstrcat(music_globals->pool,music_globals->tmp_dir,"/mp_dir_sync[",apr_itoa(music_globals->pool, i),"]",NULL); status = setup_shared_memory(&(dir->shm),sizeof(dir_sh_stats_t),dir->shm_file, music_globals->pool); if(status != 0){ return status; } //Create thread to connect to database and synchronize stats = (dir_sh_stats_t*)apr_shm_baseaddr_get(dir->shm); dir->stats = stats; stats->num_files = NULL; stats->sync_progress = 0.0; stats->files_scanned = 0; rv = apr_thread_create(&thread_sync_dir,NULL, sync_dir, (void*) dir_sync_thread, music_globals->pool); if(rv != APR_SUCCESS){ return rv; } apr_pool_cleanup_register(music_globals->pool, dir->shm,(void*) apr_shm_destroy , apr_pool_cleanup_null); } return status; }
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; }