/* * load the session from the request context, create a new one if no luck */ static apr_status_t oidc_session_load_22(request_rec *r, session_rec **zz) { oidc_cfg *c = ap_get_module_config(r->server->module_config, &auth_openidc_module); /* first see if this is a sub-request and it was set already in the main request */ if (((*zz) = (session_rec *) oidc_request_state_get(r, "session")) != NULL) { oidc_debug(r, "loading session from request state"); return APR_SUCCESS; } /* allocate space for the session object and fill it */ session_rec *z = (*zz = apr_pcalloc(r->pool, sizeof(session_rec))); z->pool = r->pool; /* get a new uuid for this session */ z->uuid = (apr_uuid_t *) apr_pcalloc(z->pool, sizeof(apr_uuid_t)); apr_uuid_get(z->uuid); z->remote_user = NULL; z->encoded = NULL; z->entries = apr_table_make(z->pool, 10); apr_status_t rc = APR_SUCCESS; if (c->session_type == OIDC_SESSION_TYPE_22_SERVER_CACHE) { /* load the session from the cache */ rc = oidc_session_load_cache(r, z); } else if (c->session_type == OIDC_SESSION_TYPE_22_CLIENT_COOKIE) { /* load the session from a self-contained cookie */ rc = oidc_session_load_cookie(r, z); } else { oidc_error(r, "oidc_session_load_22: unknown session type: %d", c->session_type); rc = APR_EGENERAL; } /* see if it worked out */ if (rc != APR_SUCCESS) return rc; /* yup, now decode the info */ if (oidc_session_identity_decode(r, z) != APR_SUCCESS) return APR_EGENERAL; /* check whether it has expired */ if (apr_time_now() > z->expiry) { oidc_warn(r, "session restored from cache has expired"); apr_table_clear(z->entries); z->expiry = 0; z->encoded = NULL; return APR_EGENERAL; } /* store this session in the request context, so it is available to sub-requests */ oidc_request_state_set(r, "session", (const char *) z); return APR_SUCCESS; }
CAMLprim value netcgi2_apache_table_clear(value tv) { CAMLparam1(tv); table *t = Table_val(tv); apr_table_clear(t); CAMLreturn(Val_unit); }
static int php_apache_sapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers) { php_struct *ctx; char *val, *ptr; ctx = SG(server_context); switch(op) { case SAPI_HEADER_DELETE: apr_table_unset(ctx->r->headers_out, sapi_header->header); return 0; case SAPI_HEADER_DELETE_ALL: apr_table_clear(ctx->r->headers_out); return 0; case SAPI_HEADER_ADD: case SAPI_HEADER_REPLACE: val = strchr(sapi_header->header, ':'); if (!val) { sapi_free_header(sapi_header); return 0; } ptr = val; *val = '\0'; do { val++; } while (*val == ' '); if (!strcasecmp(sapi_header->header, "content-type")) ctx->r->content_type = apr_pstrdup(ctx->r->pool, val); else if (!strcasecmp(sapi_header->header, "content-length")) ap_set_content_length(ctx->r, strtol(val, (char **)NULL, 10)); else if (op == SAPI_HEADER_REPLACE) apr_table_set(ctx->r->headers_out, sapi_header->header, val); else apr_table_add(ctx->r->headers_out, sapi_header->header, val); *ptr = ':'; return SAPI_HEADER_ADD; default: return 0; } }
/** * Processes one transaction phase. The phase number does not * need to be explicitly provided since it's already available * in the modsec_rec structure. */ apr_status_t modsecurity_process_phase(modsec_rec *msr, unsigned int phase) { /* Check if we should run. */ if ((msr->was_intercepted)&&(phase != PHASE_LOGGING)) { if (msr->txcfg->debuglog_level >= 4) { msr_log(msr, 4, "Skipping phase %d as request was already intercepted.", phase); } return 0; } /* Do not process the same phase twice. */ if (msr->phase >= phase) { if (msr->txcfg->debuglog_level >= 4) { msr_log(msr, 4, "Skipping phase %d because it was previously run (at %d now).", phase, msr->phase); } return 0; } msr->phase = phase; /* Clear out the transformation cache at the start of each phase */ if (msr->txcfg->cache_trans == MODSEC_CACHE_ENABLED) { if (msr->tcache) { apr_hash_index_t *hi; void *dummy; apr_table_t *tab; const void *key; apr_ssize_t klen; #ifdef CACHE_DEBUG apr_pool_t *mp = msr->msc_rule_mptmp; const apr_array_header_t *ctarr; const apr_table_entry_t *ctelts; msre_cache_rec *rec; int cn = 0; int ri; #else apr_pool_t *mp = msr->mp; #endif for (hi = apr_hash_first(mp, msr->tcache); hi; hi = apr_hash_next(hi)) { apr_hash_this(hi, &key, &klen, &dummy); tab = (apr_table_t *)dummy; if (tab == NULL) continue; #ifdef CACHE_DEBUG /* Dump the cache out as we clear */ ctarr = apr_table_elts(tab); ctelts = (const apr_table_entry_t*)ctarr->elts; for (ri = 0; ri < ctarr->nelts; ri++) { cn++; rec = (msre_cache_rec *)ctelts[ri].val; if (rec->changed) { if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "CACHE: %5d) hits=%d key=%pp %x;%s=\"%s\" (%pp - %pp)", cn, rec->hits, key, rec->num, rec->path, log_escape_nq_ex(mp, rec->val, rec->val_len), rec->val, rec->val + rec->val_len); } } else { if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "CACHE: %5d) hits=%d key=%pp %x;%s=<no change>", cn, rec->hits, key, rec->num, rec->path); } } } #endif apr_table_clear(tab); apr_hash_set(msr->tcache, key, klen, NULL); } if (msr->txcfg->debuglog_level >= 9) { msr_log(msr, 9, "Cleared transformation cache for phase %d", msr->phase); } } msr->tcache_items = 0; msr->tcache = apr_hash_make(msr->mp); if (msr->tcache == NULL) return -1; } switch(phase) { case 1 : return modsecurity_process_phase_request_headers(msr); case 2 : return modsecurity_process_phase_request_body(msr); case 3 : return modsecurity_process_phase_response_headers(msr); case 4 : return modsecurity_process_phase_response_body(msr); case 5 : return modsecurity_process_phase_logging(msr); default : msr_log(msr, 1, "Invalid processing phase: %d", msr->phase); break; } return -1; }
apr_status_t modsecurity_tx_init(modsec_rec *msr) { const char *s = NULL; const apr_array_header_t *arr; apr_table_entry_t *te; int i; /* Register TX cleanup */ apr_pool_cleanup_register(msr->mp, msr, modsecurity_tx_cleanup, apr_pool_cleanup_null); /* Initialise C-L */ msr->request_content_length = -1; s = apr_table_get(msr->request_headers, "Content-Length"); if (s != NULL) { msr->request_content_length = strtol(s, NULL, 10); } /* Figure out whether this request has a body */ msr->reqbody_chunked = 0; msr->reqbody_should_exist = 0; if (msr->request_content_length == -1) { /* There's no C-L, but is chunked encoding used? */ char *transfer_encoding = (char *)apr_table_get(msr->request_headers, "Transfer-Encoding"); if ((transfer_encoding != NULL)&&(strstr(transfer_encoding, "chunked") != NULL)) { msr->reqbody_should_exist = 1; msr->reqbody_chunked = 1; } } else { /* C-L found */ msr->reqbody_should_exist = 1; } /* Initialise C-T */ msr->request_content_type = NULL; s = apr_table_get(msr->request_headers, "Content-Type"); if (s != NULL) msr->request_content_type = s; /* Decide what to do with the request body. */ if ((msr->request_content_type != NULL) && (strncasecmp(msr->request_content_type, "application/x-www-form-urlencoded", 33) == 0)) { /* Always place POST requests with * "application/x-www-form-urlencoded" payloads in memory. */ msr->msc_reqbody_storage = MSC_REQBODY_MEMORY; msr->msc_reqbody_spilltodisk = 0; msr->msc_reqbody_processor = "URLENCODED"; } else { /* If the C-L is known and there's more data than * our limit go to disk straight away. */ if ((msr->request_content_length != -1) && (msr->request_content_length > msr->txcfg->reqbody_inmemory_limit)) { msr->msc_reqbody_storage = MSC_REQBODY_DISK; } /* In all other cases, try using the memory first * but switch over to disk for larger bodies. */ msr->msc_reqbody_storage = MSC_REQBODY_MEMORY; msr->msc_reqbody_spilltodisk = 1; if (msr->request_content_type != NULL) { if (strncasecmp(msr->request_content_type, "multipart/form-data", 19) == 0) { msr->msc_reqbody_processor = "MULTIPART"; } } } /* Check if we are forcing buffering, then use memory only. */ if (msr->txcfg->reqbody_buffering != REQUEST_BODY_FORCEBUF_OFF) { msr->msc_reqbody_storage = MSC_REQBODY_MEMORY; msr->msc_reqbody_spilltodisk = 0; } /* Initialise arguments */ msr->arguments = apr_table_make(msr->mp, 32); if (msr->arguments == NULL) return -1; if (msr->query_string != NULL) { int invalid_count = 0; if (parse_arguments(msr, msr->query_string, strlen(msr->query_string), msr->txcfg->argument_separator, "QUERY_STRING", msr->arguments, &invalid_count) < 0) { msr_log(msr, 1, "Initialisation: Error occurred while parsing QUERY_STRING arguments."); return -1; } if (invalid_count) { msr->urlencoded_error = 1; } } msr->arguments_to_sanitize = apr_table_make(msr->mp, 16); if (msr->arguments_to_sanitize == NULL) return -1; msr->request_headers_to_sanitize = apr_table_make(msr->mp, 16); if (msr->request_headers_to_sanitize == NULL) return -1; msr->response_headers_to_sanitize = apr_table_make(msr->mp, 16); if (msr->response_headers_to_sanitize == NULL) return -1; msr->pattern_to_sanitize = apr_table_make(msr->mp, 32); if (msr->pattern_to_sanitize == NULL) return -1; /* remove targets */ msr->removed_targets = apr_table_make(msr->mp, 16); if (msr->removed_targets == NULL) return -1; /* Initialise cookies */ msr->request_cookies = apr_table_make(msr->mp, 16); if (msr->request_cookies == NULL) return -1; /* Initialize matched vars */ msr->matched_vars = apr_table_make(msr->mp, 8); if (msr->matched_vars == NULL) return -1; apr_table_clear(msr->matched_vars); if(msr->txcfg->max_rule_time > 0) { msr->perf_rules = apr_table_make(msr->mp, 8); if (msr->perf_rules == NULL) return -1; apr_table_clear(msr->perf_rules); } /* Locate the cookie headers and parse them */ arr = apr_table_elts(msr->request_headers); te = (apr_table_entry_t *)arr->elts; for (i = 0; i < arr->nelts; i++) { if (strcasecmp(te[i].key, "Cookie") == 0) { if (msr->txcfg->cookie_format == COOKIES_V0) { parse_cookies_v0(msr, te[i].val, msr->request_cookies); } else { parse_cookies_v1(msr, te[i].val, msr->request_cookies); } } } /* Collections. */ msr->tx_vars = apr_table_make(msr->mp, 32); if (msr->tx_vars == NULL) return -1; msr->geo_vars = apr_table_make(msr->mp, 8); if (msr->geo_vars == NULL) return -1; msr->collections_original = apr_table_make(msr->mp, 8); if (msr->collections_original == NULL) return -1; msr->collections = apr_table_make(msr->mp, 8); if (msr->collections == NULL) return -1; msr->collections_dirty = apr_table_make(msr->mp, 8); if (msr->collections_dirty == NULL) return -1; /* Other */ msr->tcache = NULL; msr->tcache_items = 0; msr->matched_rules = apr_array_make(msr->mp, 16, sizeof(void *)); if (msr->matched_rules == NULL) return -1; msr->matched_var = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string)); if (msr->matched_var == NULL) return -1; msr->highest_severity = 255; /* high, invalid value */ msr->removed_rules = apr_array_make(msr->mp, 16, sizeof(char *)); if (msr->removed_rules == NULL) return -1; msr->removed_rules_tag = apr_array_make(msr->mp, 16, sizeof(char *)); if (msr->removed_rules_tag == NULL) return -1; msr->removed_rules_msg = apr_array_make(msr->mp, 16, sizeof(char *)); if (msr->removed_rules_msg == NULL) return -1; return 1; }
static int php_apache_sapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers) { php_struct *ctx; char *val, *ptr; ctx = SG(server_context); switch (op) { case SAPI_HEADER_DELETE: apr_table_unset(ctx->r->headers_out, sapi_header->header); return 0; case SAPI_HEADER_DELETE_ALL: apr_table_clear(ctx->r->headers_out); return 0; case SAPI_HEADER_ADD: case SAPI_HEADER_REPLACE: val = strchr(sapi_header->header, ':'); if (!val) { return 0; } ptr = val; *val = '\0'; do { val++; } while (*val == ' '); if (!strcasecmp(sapi_header->header, "content-type")) { if (ctx->content_type) { efree(ctx->content_type); } ctx->content_type = estrdup(val); } else if (!strcasecmp(sapi_header->header, "content-length")) { apr_off_t clen = 0; if (APR_SUCCESS != apr_strtoff(&clen, val, (char **) NULL, 10)) { /* We'll fall back to strtol, since that's what we used to * do anyway. */ clen = (apr_off_t) strtol(val, (char **) NULL, 10); } ap_set_content_length(ctx->r, clen); } else if (op == SAPI_HEADER_REPLACE) { apr_table_set(ctx->r->headers_out, sapi_header->header, val); } else { apr_table_add(ctx->r->headers_out, sapi_header->header, val); } *ptr = ':'; return SAPI_HEADER_ADD; default: return 0; } }
static void table_clear(abts_case *tc, void *data) { apr_table_clear(t1); ABTS_INT_EQUAL(tc, 0, apr_table_elts(t1)->nelts); }
/* Process authentication request from Apache*/ static int pg_authenticate_basic_user(request_rec * r) { pg_auth_config_rec *sec = (pg_auth_config_rec *) ap_get_module_config(r->per_dir_config, &auth_pgsql_module); char *val = NULL; char *sent_pw, *real_pw; int res; char *user; if ((res = ap_get_basic_auth_pw(r, (const char **) &sent_pw))) return res; user = r->user; #ifdef DEBUG_AUTH_PGSQL ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "[mod_auth_pgsql.c] - pg_authenticate_basic_user - going to auth user \"%s\" pass \"%s\" uri \"%s\"", user, sent_pw, r->unparsed_uri); #endif /* DEBUG_AUTH_PGSQL */ /* if *password* checking is configured in any way, i.e. then * handle it, if not decline and leave it to the next in line.. * We do not check on dbase, group, userid or host name, as it is * perfectly possible to only do group control and leave * user control to the next guy in line. */ if ((!sec->auth_pg_pwd_table) && (!sec->auth_pg_pwd_field)) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "[mod_auth_pgsql.c] - missing configuration parameters"); return DECLINED; } pg_errstr[0] = '\0'; if (sec->auth_pg_cache_passwords && (!apr_is_empty_table(sec->cache_pass_table))) { val = (char *) apr_table_get(sec->cache_pass_table, user); if (val) real_pw = val; else real_pw = get_pg_pw(r, user, sec); } else real_pw = get_pg_pw(r, user, sec); if (!real_pw) { if (pg_errstr[0]) { res = HTTP_INTERNAL_SERVER_ERROR; } else { if (sec->auth_pg_authoritative) { /* force error and access denied */ apr_snprintf(pg_errstr, MAX_STRING_LEN, "mod_auth_pgsql: Password for user %s not found (PG-Authoritative)", user); ap_note_basic_auth_failure(r); res = HTTP_UNAUTHORIZED; } else { /* allow fall through to another module */ return DECLINED; } } ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr); return res; } /* allow no password, if the flag is set and the password * is empty. But be sure to log this. */ if ((sec->auth_pg_nopasswd) && (!strlen(real_pw))) { apr_snprintf(pg_errstr, MAX_STRING_LEN, "[mod_auth_pgsql.c] - Empty password accepted for user \"%s\"", user); ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr); pg_log_auth_user(r, sec, user, sent_pw); return OK; }; /* if the flag is off however, keep that kind of stuff at * an arms length. */ if ((!strlen(real_pw)) || (!strlen(sent_pw))) { apr_snprintf(pg_errstr, MAX_STRING_LEN, "[mod_auth_pgsql.c] - Empty password rejected for user \"%s\"", user); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr); ap_note_basic_auth_failure(r); return HTTP_UNAUTHORIZED; }; if (sec->auth_pg_encrypted) switch (sec->auth_pg_hash_type) { case AUTH_PG_HASH_TYPE_MD5: sent_pw = auth_pg_md5(sent_pw); break; case AUTH_PG_HASH_TYPE_CRYPT: sent_pw = (char *) crypt(sent_pw, real_pw); break; case AUTH_PG_HASH_TYPE_BASE64: sent_pw = auth_pg_base64(sent_pw); break; } if (sec->auth_pg_hash_type == AUTH_PG_HASH_TYPE_NETEPI) { char *netepi_pw; if (netepi_pw = netepi_pwd_check(sec, r, real_pw, sent_pw)) goto netepi_ok; apr_snprintf(pg_errstr, MAX_STRING_LEN, "PG user %s: password mismatch", user); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr); ap_note_basic_auth_failure(r); return HTTP_UNAUTHORIZED; netepi_ok: sent_pw = netepi_pw; } else if ((sec->auth_pg_hash_type == AUTH_PG_HASH_TYPE_MD5 || sec->auth_pg_hash_type == AUTH_PG_HASH_TYPE_BASE64 || sec->auth_pg_pwdignorecase) ? strcasecmp(real_pw, sent_pw) : strcmp(real_pw, sent_pw)) { apr_snprintf(pg_errstr, MAX_STRING_LEN, "PG user %s: password mismatch", user); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "[mod_auth_pgsql.c] - ERROR - %s", pg_errstr); ap_note_basic_auth_failure(r); return HTTP_UNAUTHORIZED; } /* store password in the cache */ if (sec->auth_pg_cache_passwords && !val && sec->cache_pass_table) { if ((apr_table_elts(sec->cache_pass_table))->nelts >= MAX_TABLE_LEN) { apr_table_clear(sec->cache_pass_table); } apr_table_set(sec->cache_pass_table, user, real_pw); } pg_log_auth_user(r, sec, user, sent_pw); return OK; }
static apr_status_t readfile_heartbeats(const char *path, apr_hash_t *servers, apr_pool_t *pool) { apr_finfo_t fi; apr_status_t rv; apr_file_t *fp; if (!path) { return APR_SUCCESS; } rv = apr_file_open(&fp, path, APR_READ|APR_BINARY|APR_BUFFERED, APR_OS_DEFAULT, pool); if (rv) { return rv; } rv = apr_file_info_get(&fi, APR_FINFO_SIZE, fp); if (rv) { return rv; } { char *t; int lineno = 0; apr_bucket_alloc_t *ba = apr_bucket_alloc_create(pool); apr_bucket_brigade *bb = apr_brigade_create(pool, ba); apr_bucket_brigade *tmpbb = apr_brigade_create(pool, ba); apr_table_t *hbt = apr_table_make(pool, 10); apr_brigade_insert_file(bb, fp, 0, fi.size, pool); do { hb_server_t *server; char buf[4096]; apr_size_t bsize = sizeof(buf); const char *ip; apr_brigade_cleanup(tmpbb); if (APR_BRIGADE_EMPTY(bb)) { break; } rv = apr_brigade_split_line(tmpbb, bb, APR_BLOCK_READ, sizeof(buf)); lineno++; if (rv) { return rv; } apr_brigade_flatten(tmpbb, buf, &bsize); if (bsize == 0) { break; } buf[bsize - 1] = 0; /* comment */ if (buf[0] == '#') { continue; } /* line format: <IP> <query_string>\n */ t = strchr(buf, ' '); if (!t) { continue; } ip = apr_pstrmemdup(pool, buf, t - buf); t++; server = apr_hash_get(servers, ip, APR_HASH_KEY_STRING); if (server == NULL) { server = apr_pcalloc(pool, sizeof(hb_server_t)); server->ip = ip; server->port = 80; server->seen = -1; apr_hash_set(servers, server->ip, APR_HASH_KEY_STRING, server); } apr_table_clear(hbt); argstr_to_table(pool, apr_pstrdup(pool, t), hbt); if (apr_table_get(hbt, "busy")) { server->busy = atoi(apr_table_get(hbt, "busy")); } if (apr_table_get(hbt, "ready")) { server->ready = atoi(apr_table_get(hbt, "ready")); } if (apr_table_get(hbt, "lastseen")) { server->seen = atoi(apr_table_get(hbt, "lastseen")); } if (apr_table_get(hbt, "port")) { server->port = atoi(apr_table_get(hbt, "port")); } if (server->busy == 0 && server->ready != 0) { /* Server has zero threads active, but lots of them ready, * it likely just started up, so lets /4 the number ready, * to prevent us from completely flooding it with all new * requests. */ server->ready = server->ready / 4; } } while (1); } return APR_SUCCESS; }
apr_status_t modsecurity_tx_init(modsec_rec *msr) { const char *s = NULL; /* Register TX cleanup */ apr_pool_cleanup_register(msr->mp, msr, modsecurity_tx_cleanup, apr_pool_cleanup_null); /* Initialise C-L */ msr->request_content_length = -1; s = apr_table_get(msr->request_headers, "Content-Length"); if (s != NULL) { msr->request_content_length = strtol(s, NULL, 10); } /* Figure out whether this request has a body */ msr->reqbody_chunked = 0; msr->reqbody_should_exist = 0; if (msr->request_content_length == -1) { /* There's no C-L, but is chunked encoding used? */ char *transfer_encoding = (char *)apr_table_get(msr->request_headers, "Transfer-Encoding"); if ((transfer_encoding != NULL) && (strstr(transfer_encoding, "chunked") != NULL)) { msr->reqbody_should_exist = 1; msr->reqbody_chunked = 1; } } else { /* C-L found */ msr->reqbody_should_exist = 1; } /* Initialise C-T */ msr->request_content_type = NULL; s = apr_table_get(msr->request_headers, "Content-Type"); if (s != NULL) { msr->request_content_type = s; } /* Decide what to do with the request body. */ if ((msr->request_content_type != NULL) && (strncasecmp(msr->request_content_type, "application/x-www-form-urlencoded", 33) == 0)) { /* Always place POST requests with "application/x-www-form-urlencoded" payloads in memory. */ msr->msc_reqbody_storage = MSC_REQBODY_MEMORY; msr->msc_reqbody_spilltodisk = 1; msr->msc_reqbody_processor = "URLENCODED"; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "msc reqbody processor change to URLENCODED"); } else { /* In all other cases, try using the memory first but switch over to disk for larger bodies. */ msr->msc_reqbody_storage = MSC_REQBODY_MEMORY; msr->msc_reqbody_spilltodisk = 1; /* If the C-L is known and there's more data than our limit go to disk straight away. */ if ((msr->request_content_length != -1) && (msr->request_content_length > msr->txcfg->reqbody_inmemory_limit)) { msr->msc_reqbody_storage = MSC_REQBODY_DISK; } if (msr->request_content_type != NULL) { if (strncasecmp(msr->request_content_type, "multipart/form-data", 19) == 0) { msr->msc_reqbody_processor = "MULTIPART"; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "msc reqbody processor change to MULTIPART"); } else if (strncasecmp(msr->request_content_type, "text/xml", 8) == 0) { msr->msc_reqbody_processor = "XML"; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, NULL, "msc reqbody processor change to XML"); } } } /* Check if we are forcing buffering, then use memory only. */ if (msr->txcfg->reqbody_buffering != REQUEST_BODY_FORCEBUF_OFF) { msr->msc_reqbody_storage = MSC_REQBODY_MEMORY; msr->msc_reqbody_spilltodisk = 0; } /* Initialise arguments */ msr->arguments = apr_table_make(msr->mp, 32); if (msr->arguments == NULL) { return -1; } if (msr->query_string != NULL) { int invalid_count = 0; /* 查询串参数解析 */ if (parse_arguments(msr, msr->query_string, strlen(msr->query_string), msr->txcfg->argument_separator, "QUERY_STRING", msr->arguments, &invalid_count) < 0) { msr_log(msr, 1, "Initialisation: Error occurred while parsing QUERY_STRING arguments."); return -1; } if (invalid_count) { msr->urlencoded_error = 1; } } if (msr->request_uri != NULL) { /* request_uri解析 */ msr->request_uri = (const char *)parse_uri(msr->mp, msr->request_uri); if (msr->request_uri == NULL) { msr_log(msr, 1, "Initialisation: Error occurred while parsing REQUEST_URI arguments."); return -1; } } if (msr->request_line != NULL) { /* request_line解析 */ msr->request_line = (const char *)parse_request_line(msr->mp, msr->request_line); if (msr->request_line == NULL) { msr_log(msr, 1, "Initialisation: Error occurred while parsing REQUEST_LINE arguments."); return -1; } } msr->arguments_to_sanitize = apr_table_make(msr->mp, 16); if (msr->arguments_to_sanitize == NULL) { return -1; } msr->request_headers_to_sanitize = apr_table_make(msr->mp, 16); if (msr->request_headers_to_sanitize == NULL) { return -1; } msr->response_headers_to_sanitize = apr_table_make(msr->mp, 16); if (msr->response_headers_to_sanitize == NULL) { return -1; } msr->pattern_to_sanitize = apr_table_make(msr->mp, 32); if (msr->pattern_to_sanitize == NULL) { return -1; } /* Initialise cookies */ msr->request_cookies = apr_table_make(msr->mp, 5); if (msr->request_cookies == NULL) { return -1; } /* Initialize matched vars */ msr->matched_vars = apr_table_make(msr->mp, 8); if (msr->matched_vars == NULL) { return -1; } apr_table_clear(msr->matched_vars); /* Locate the cookie headers and parse them */ /* 解析请求cookie */ if (parse_request_cookie(msr) == -1) { return -1; } /* Collections. */ msr->tx_vars = apr_table_make(msr->mp, 32); if (msr->tx_vars == NULL) { return -1; } msr->geo_vars = apr_table_make(msr->mp, 8); if (msr->geo_vars == NULL) { return -1; } msr->collections_original = apr_table_make(msr->mp, 8); if (msr->collections_original == NULL) { return -1; } msr->collections = apr_table_make(msr->mp, 8); if (msr->collections == NULL) { return -1; } msr->collections_dirty = apr_table_make(msr->mp, 8); if (msr->collections_dirty == NULL) { return -1; } /* Other */ msr->tcache = NULL; msr->tcache_items = 0; /* 初始化变量缓存内存池 */ #ifdef VAR_FETCH_CACHE if (apr_pool_create(&msr->var_fetch_cache_mptmp, msr->mp) != APR_SUCCESS) { return -1; } apr_pool_tag(msr->var_fetch_cache_mptmp, "varfetchcache"); #endif msr->matched_rules = apr_array_make(msr->mp, 16, sizeof(void *)); if (msr->matched_rules == NULL) { return -1; } msr->matched_var = (msc_string *)apr_pcalloc(msr->mp, sizeof(msc_string)); if (msr->matched_var == NULL) { return -1; } msr->highest_severity = 255; /* high, invalid value */ msr->removed_rules = apr_array_make(msr->mp, 16, sizeof(char *)); if (msr->removed_rules == NULL) { return -1; } msr->removed_rules_tag = apr_array_make(msr->mp, 16, sizeof(char *)); if (msr->removed_rules_tag == NULL) { return -1; } return 1; }
static int php_apache_sapi_header_handler(sapi_header_struct *sapi_header, sapi_header_op_enum op, sapi_headers_struct *sapi_headers) { php_struct *ctx; char *val, *ptr; ctx = SG(server_context); switch (op) { case SAPI_HEADER_DELETE: apr_table_unset(ctx->r->headers_out, sapi_header->header); return 0; case SAPI_HEADER_DELETE_ALL: apr_table_clear(ctx->r->headers_out); return 0; case SAPI_HEADER_ADD: case SAPI_HEADER_REPLACE: val = strchr(sapi_header->header, ':'); if (!val) { return 0; } ptr = val; *val = '\0'; do { val++; } while (*val == ' '); if (!strcasecmp(sapi_header->header, "content-type")) { if (ctx->content_type) { efree(ctx->content_type); } ctx->content_type = estrdup(val); } else if (!strcasecmp(sapi_header->header, "content-length")) { #ifdef PHP_WIN32 # ifdef APR_HAS_LARGE_FILES ap_set_content_length(ctx->r, (apr_off_t) _strtoui64(val, (char **)NULL, 10)); # else ap_set_content_length(ctx->r, (apr_off_t) strtol(val, (char **)NULL, 10)); # endif #else ap_set_content_length(ctx->r, (apr_off_t) strtol(val, (char **)NULL, 10)); #endif } else if (op == SAPI_HEADER_REPLACE) { apr_table_set(ctx->r->headers_out, sapi_header->header, val); } else { apr_table_add(ctx->r->headers_out, sapi_header->header, val); } *ptr = ':'; return SAPI_HEADER_ADD; default: return 0; } }
/* Manages the loadfactors and member status */ static int balancer_handler(request_rec *r) { void *sconf = r->server->module_config; proxy_server_conf *conf = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); proxy_balancer *balancer, *bsel = NULL; proxy_worker *worker, *wsel = NULL; apr_table_t *params = apr_table_make(r->pool, 10); int access_status; int i, n; const char *name; /* is this for us? */ if (strcmp(r->handler, "balancer-manager")) return DECLINED; r->allowed = (AP_METHOD_BIT << M_GET); if (r->method_number != M_GET) return DECLINED; if (r->args) { char *args = apr_pstrdup(r->pool, r->args); char *tok, *val; while (args && *args) { if ((val = ap_strchr(args, '='))) { *val++ = '\0'; if ((tok = ap_strchr(val, '&'))) *tok++ = '\0'; /* * Special case: workers are allowed path information */ if ((access_status = ap_unescape_url(val)) != OK) if (strcmp(args, "w") || (access_status != HTTP_NOT_FOUND)) return access_status; apr_table_setn(params, args, val); args = tok; } else return HTTP_BAD_REQUEST; } } /* Check that the supplied nonce matches this server's nonce; * otherwise ignore all parameters, to prevent a CSRF attack. */ if ((name = apr_table_get(params, "nonce")) == NULL || strcmp(balancer_nonce, name) != 0) { apr_table_clear(params); } if ((name = apr_table_get(params, "b"))) bsel = ap_proxy_get_balancer(r->pool, conf, apr_pstrcat(r->pool, "balancer://", name, NULL)); if ((name = apr_table_get(params, "w"))) { proxy_worker *ws; ws = ap_proxy_get_worker(r->pool, conf, name); if (bsel && ws) { worker = (proxy_worker *)bsel->workers->elts; for (n = 0; n < bsel->workers->nelts; n++) { if (strcasecmp(worker->name, ws->name) == 0) { wsel = worker; break; } ++worker; } } } /* First set the params */ /* * Note that it is not possible set the proxy_balancer because it is not * in shared memory. */ if (wsel) { const char *val; if ((val = apr_table_get(params, "lf"))) { int ival = atoi(val); if (ival >= 1 && ival <= 100) { wsel->s->lbfactor = ival; if (bsel) recalc_factors(bsel); } } if ((val = apr_table_get(params, "wr"))) { if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ) strcpy(wsel->s->route, val); else *wsel->s->route = '\0'; } if ((val = apr_table_get(params, "rr"))) { if (strlen(val) && strlen(val) < PROXY_WORKER_MAX_ROUTE_SIZ) strcpy(wsel->s->redirect, val); else *wsel->s->redirect = '\0'; } if ((val = apr_table_get(params, "dw"))) { if (!strcasecmp(val, "Disable")) wsel->s->status |= PROXY_WORKER_DISABLED; else if (!strcasecmp(val, "Enable")) wsel->s->status &= ~PROXY_WORKER_DISABLED; } if ((val = apr_table_get(params, "ls"))) { int ival = atoi(val); if (ival >= 0 && ival <= 99) { wsel->s->lbset = ival; } } } if (apr_table_get(params, "xml")) { ap_set_content_type(r, "text/xml"); ap_rputs("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n", r); ap_rputs("<httpd:manager xmlns:httpd=\"http://httpd.apache.org\">\n", r); ap_rputs(" <httpd:balancers>\n", r); balancer = (proxy_balancer *)conf->balancers->elts; for (i = 0; i < conf->balancers->nelts; i++) { ap_rputs(" <httpd:balancer>\n", r); ap_rvputs(r, " <httpd:name>", balancer->name, "</httpd:name>\n", NULL); ap_rputs(" <httpd:workers>\n", r); worker = (proxy_worker *)balancer->workers->elts; for (n = 0; n < balancer->workers->nelts; n++) { ap_rputs(" <httpd:worker>\n", r); ap_rvputs(r, " <httpd:scheme>", worker->scheme, "</httpd:scheme>\n", NULL); ap_rvputs(r, " <httpd:hostname>", worker->hostname, "</httpd:hostname>\n", NULL); ap_rprintf(r, " <httpd:loadfactor>%d</httpd:loadfactor>\n", worker->s->lbfactor); ap_rputs(" </httpd:worker>\n", r); ++worker; } ap_rputs(" </httpd:workers>\n", r); ap_rputs(" </httpd:balancer>\n", r); ++balancer; } ap_rputs(" </httpd:balancers>\n", r); ap_rputs("</httpd:manager>", r); } else { ap_set_content_type(r, "text/html; charset=ISO-8859-1"); ap_rputs(DOCTYPE_HTML_3_2 "<html><head><title>Balancer Manager</title></head>\n", r); ap_rputs("<body><h1>Load Balancer Manager for ", r); ap_rvputs(r, ap_get_server_name(r), "</h1>\n\n", NULL); ap_rvputs(r, "<dl><dt>Server Version: ", ap_get_server_description(), "</dt>\n", NULL); ap_rvputs(r, "<dt>Server Built: ", ap_get_server_built(), "\n</dt></dl>\n", NULL); balancer = (proxy_balancer *)conf->balancers->elts; for (i = 0; i < conf->balancers->nelts; i++) { ap_rputs("<hr />\n<h3>LoadBalancer Status for ", r); ap_rvputs(r, balancer->name, "</h3>\n\n", NULL); ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>" "<th>StickySession</th><th>Timeout</th><th>FailoverAttempts</th><th>Method</th>" "</tr>\n<tr>", r); if (balancer->sticky) { ap_rvputs(r, "<td>", balancer->sticky, NULL); } else { ap_rputs("<td> - ", r); } ap_rprintf(r, "</td><td>%" APR_TIME_T_FMT "</td>", apr_time_sec(balancer->timeout)); ap_rprintf(r, "<td>%d</td>\n", balancer->max_attempts); ap_rprintf(r, "<td>%s</td>\n", balancer->lbmethod->name); ap_rputs("</table>\n<br />", r); ap_rputs("\n\n<table border=\"0\" style=\"text-align: left;\"><tr>" "<th>Worker URL</th>" "<th>Route</th><th>RouteRedir</th>" "<th>Factor</th><th>Set</th><th>Status</th>" "<th>Elected</th><th>To</th><th>From</th>" "</tr>\n", r); worker = (proxy_worker *)balancer->workers->elts; for (n = 0; n < balancer->workers->nelts; n++) { char fbuf[50]; ap_rvputs(r, "<tr>\n<td><a href=\"", r->uri, "?b=", balancer->name + sizeof("balancer://") - 1, "&w=", ap_escape_uri(r->pool, worker->name), "&nonce=", balancer_nonce, "\">", NULL); ap_rvputs(r, worker->name, "</a></td>", NULL); ap_rvputs(r, "<td>", ap_escape_html(r->pool, worker->s->route), NULL); ap_rvputs(r, "</td><td>", ap_escape_html(r->pool, worker->s->redirect), NULL); ap_rprintf(r, "</td><td>%d</td>", worker->s->lbfactor); ap_rprintf(r, "<td>%d</td><td>", worker->s->lbset); if (worker->s->status & PROXY_WORKER_DISABLED) ap_rputs("Dis ", r); if (worker->s->status & PROXY_WORKER_IN_ERROR) ap_rputs("Err ", r); if (worker->s->status & PROXY_WORKER_STOPPED) ap_rputs("Stop ", r); if (worker->s->status & PROXY_WORKER_HOT_STANDBY) ap_rputs("Stby ", r); if (PROXY_WORKER_IS_USABLE(worker)) ap_rputs("Ok", r); if (!PROXY_WORKER_IS_INITIALIZED(worker)) ap_rputs("-", r); ap_rputs("</td>", r); ap_rprintf(r, "<td>%" APR_SIZE_T_FMT "</td><td>", worker->s->elected); ap_rputs(apr_strfsize(worker->s->transferred, fbuf), r); ap_rputs("</td><td>", r); ap_rputs(apr_strfsize(worker->s->read, fbuf), r); ap_rputs("</td></tr>\n", r); ++worker; } ap_rputs("</table>\n", r); ++balancer; } ap_rputs("<hr />\n", r); if (wsel && bsel) { ap_rputs("<h3>Edit worker settings for ", r); ap_rvputs(r, wsel->name, "</h3>\n", NULL); ap_rvputs(r, "<form method=\"GET\" action=\"", NULL); ap_rvputs(r, r->uri, "\">\n<dl>", NULL); ap_rputs("<table><tr><td>Load factor:</td><td><input name=\"lf\" type=text ", r); ap_rprintf(r, "value=\"%d\"></td></tr>\n", wsel->s->lbfactor); ap_rputs("<tr><td>LB Set:</td><td><input name=\"ls\" type=text ", r); ap_rprintf(r, "value=\"%d\"></td></tr>\n", wsel->s->lbset); ap_rputs("<tr><td>Route:</td><td><input name=\"wr\" type=text ", r); ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->route), NULL); ap_rputs("\"></td></tr>\n", r); ap_rputs("<tr><td>Route Redirect:</td><td><input name=\"rr\" type=text ", r); ap_rvputs(r, "value=\"", ap_escape_html(r->pool, wsel->s->redirect), NULL); ap_rputs("\"></td></tr>\n", r); ap_rputs("<tr><td>Status:</td><td>Disabled: <input name=\"dw\" value=\"Disable\" type=radio", r); if (wsel->s->status & PROXY_WORKER_DISABLED) ap_rputs(" checked", r); ap_rputs("> | Enabled: <input name=\"dw\" value=\"Enable\" type=radio", r); if (!(wsel->s->status & PROXY_WORKER_DISABLED)) ap_rputs(" checked", r); ap_rputs("></td></tr>\n", r); ap_rputs("<tr><td colspan=2><input type=submit value=\"Submit\"></td></tr>\n", r); ap_rvputs(r, "</table>\n<input type=hidden name=\"w\" ", NULL); ap_rvputs(r, "value=\"", ap_escape_uri(r->pool, wsel->name), "\">\n", NULL); ap_rvputs(r, "<input type=hidden name=\"b\" ", NULL); ap_rvputs(r, "value=\"", bsel->name + sizeof("balancer://") - 1, "\">\n", NULL); ap_rvputs(r, "<input type=hidden name=\"nonce\" value=\"", balancer_nonce, "\">\n", NULL); ap_rvputs(r, "</form>\n", NULL); ap_rputs("<hr />\n", r); } ap_rputs(ap_psignature("",r), r); ap_rputs("</body></html>\n", r); } return OK; }
apr_status_t oidc_session_kill(request_rec *r, session_rec *z) { apr_table_clear(z->entries); z->expiry = 0; z->encoded = NULL; return ap_session_save_fn(r, z); }