void jaxer_add_env_vars(request_rec * r) { /* * Add additonal vars that are needed by jaxer. * REMOTE_USER * REMOTE_HOST * STATUS_CODE * HTTPS */ apr_table_t *env = r->subprocess_env; jaxer_dir_conf *config = ap_get_module_config(r->per_dir_config, &jaxer_module); int is_ip; int ssl_on; const char * ru = ap_get_remote_logname(r); #ifndef APACHE1_3 const char * rh = ap_get_remote_host(r->connection, config, REMOTE_NAME, &is_ip); #else const char * rh = ap_get_remote_host(r->connection, config, REMOTE_NAME); #endif if (ru) apr_table_setn(env, "REMOTE_USER", ru); // else // apr_table_setn(env, "REMOTE_USER", ""); if (rh && !is_ip) ap_table_setn(env, "REMOTE_HOST", rh); ap_table_setn(env, "STATUS_CODE", ap_psprintf(r->pool, "%d", r->status)); ssl_on = jaxer_conn_is_https(r->connection); ap_table_setn(env, "HTTPS", ap_psprintf(r->pool, "%s", (ssl_on != 0)? "on" : "off" )); }
static int update_child_status_internal(int child_num, int thread_num, int status, conn_rec *c, request_rec *r) { int old_status; worker_score *ws; process_score *ps; int mpm_generation; ws = &ap_scoreboard_image->servers[child_num][thread_num]; old_status = ws->status; ws->status = status; ps = &ap_scoreboard_image->parent[child_num]; if (status == SERVER_READY && old_status == SERVER_STARTING) { ws->thread_num = child_num * thread_limit + thread_num; ap_mpm_query(AP_MPMQ_GENERATION, &mpm_generation); ps->generation = mpm_generation; } if (ap_extended_status) { ws->last_used = apr_time_now(); if (status == SERVER_READY || status == SERVER_DEAD) { /* * Reset individual counters */ if (status == SERVER_DEAD) { ws->my_access_count = 0L; ws->my_bytes_served = 0L; } ws->conn_count = 0; ws->conn_bytes = 0; } if (r) { apr_cpystrn(ws->client, ap_get_remote_host(c, r->per_dir_config, REMOTE_NOLOOKUP, NULL), sizeof(ws->client)); copy_request(ws->request, sizeof(ws->request), r); if (r->server) { apr_snprintf(ws->vhost, sizeof(ws->vhost), "%s:%d", r->server->server_hostname, r->connection->local_addr->port); } } else if (c) { apr_cpystrn(ws->client, ap_get_remote_host(c, NULL, REMOTE_NOLOOKUP, NULL), sizeof(ws->client)); ws->request[0]='\0'; ws->vhost[0]='\0'; } } return old_status; }
static int update_echo_child_status(ap_sb_handle_t *sbh, int status, conn_rec *c, apr_bucket_brigade *last_echoed) { worker_score *ws = ap_get_scoreboard_worker(sbh); int old_status = ws->status; ws->status = status; if (!ap_extended_status) return old_status; ws->last_used = apr_time_now(); /* initial pass only, please - in the name of efficiency */ if (c) { apr_cpystrn(ws->client, ap_get_remote_host(c, c->base_server->lookup_defaults, REMOTE_NOLOOKUP, NULL), sizeof(ws->client)); apr_cpystrn(ws->vhost, c->base_server->server_hostname, sizeof(ws->vhost)); /* Deliberate trailing space - filling in string on WRITE passes */ apr_cpystrn(ws->request, "ECHO ", sizeof(ws->request)); } /* each subsequent WRITE pass, let's update what we echoed */ if (last_echoed) { brigade_peek(last_echoed, ws->request + sizeof("ECHO ") - 1, sizeof(ws->request) - sizeof("ECHO ") + 1); } return old_status; }
API_EXPORT(void) ap_log_reason (const char *reason, const char *file, request_rec *r) { ap_log_error(APLOG_MARK, APLOG_ERR, r->server, "access to %s failed for %s, reason: %s", file, ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME), reason); }
static int req_get_remote_host(lua_State *L) { request_rec *r = CHECK_REQUEST_OBJECT(1); int type = (int)luaL_optnumber(L, 2, REMOTE_NOLOOKUP); int str_is_ip; lua_pushstring (L, ap_get_remote_host (r->connection, r->per_dir_config, type , &str_is_ip)); lua_pushnumber(L, str_is_ip); return 2; }
static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method) { allowdeny *ap = (allowdeny *) a->elts; apr_int64_t mmask = (AP_METHOD_BIT << method); int i; int gothost = 0; const char *remotehost = NULL; for (i = 0; i < a->nelts; ++i) { if (!(mmask & ap[i].limited)) continue; switch (ap[i].type) { case T_ENV: if (apr_table_get(r->subprocess_env, ap[i].x.from)) { return 1; } break; case T_ALL: return 1; case T_IP: if (apr_ipsubnet_test(ap[i].x.ip, r->connection->remote_addr)) { return 1; } break; case T_HOST: if (!gothost) { int remotehost_is_ip; remotehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_DOUBLE_REV, &remotehost_is_ip); if ((remotehost == NULL) || remotehost_is_ip) gothost = 1; else gothost = 2; } if ((gothost == 2) && in_domain(ap[i].x.from, remotehost)) return 1; break; case T_FAIL: /* do nothing? */ break; } } return 0; }
static int find_allowdeny(request_rec *r, array_header *a, int method) { allowdeny *ap = (allowdeny *) a->elts; int mmask = (1 << method); int i; int gothost = 0; const char *remotehost = NULL; for (i = 0; i < a->nelts; ++i) { if (!(mmask & ap[i].limited)) continue; switch (ap[i].type) { case T_ENV: if (ap_table_get(r->subprocess_env, ap[i].x.from)) { return 1; } break; case T_ALL: return 1; case T_IP: if (ap[i].x.ip.net.s_addr != INADDR_NONE && (r->connection->remote_addr.sin_addr.s_addr & ap[i].x.ip.mask.s_addr) == ap[i].x.ip.net.s_addr) { return 1; } break; case T_HOST: if (!gothost) { remotehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_DOUBLE_REV); if ((remotehost == NULL) || is_ip(remotehost)) gothost = 1; else gothost = 2; } if ((gothost == 2) && in_domain(ap[i].x.from, remotehost)) return 1; break; case T_FAIL: /* do nothing? */ break; } } return 0; }
static authn_status pam_authenticate_with_login_password(request_rec * r, const char * pam_service, const char * login, const char * password, int steps) { pam_handle_t * pamh = NULL; struct pam_conv pam_conversation = { &pam_authenticate_conv, (void *) password }; const char * stage = "PAM transaction failed for service"; const char * param = pam_service; int ret; ret = pam_start(pam_service, login, &pam_conversation, &pamh); if (ret == PAM_SUCCESS) { const char * remote_host_or_ip = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL); if (remote_host_or_ip) { stage = "PAM pam_set_item PAM_RHOST failed for service"; ret = pam_set_item(pamh, PAM_RHOST, remote_host_or_ip); } } if (ret == PAM_SUCCESS) { if (steps & _PAM_STEP_AUTH) { param = login; stage = "PAM authentication failed for user"; ret = pam_authenticate(pamh, PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK); } if ((ret == PAM_SUCCESS) && (steps & _PAM_STEP_ACCOUNT)) { param = login; stage = "PAM account validation failed for user"; ret = pam_acct_mgmt(pamh, PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK); if (ret == PAM_NEW_AUTHTOK_REQD) { authnz_pam_config_rec * conf = ap_get_module_config(r->per_dir_config, &authnz_pam_module); if (conf && conf->expired_redirect_url) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "mod_authnz_pam: PAM_NEW_AUTHTOK_REQD: redirect to [%s]", conf->expired_redirect_url); apr_table_addn(r->headers_out, "Location", format_location(r, conf->expired_redirect_url, login)); return HTTP_TEMPORARY_REDIRECT; } } } } if (ret != PAM_SUCCESS) { const char * strerr = pam_strerror(pamh, ret); ap_log_error(APLOG_MARK, APLOG_WARNING, 0, r->server, "mod_authnz_pam: %s %s: %s", stage, param, strerr); apr_table_setn(r->subprocess_env, _EXTERNAL_AUTH_ERROR_ENV_NAME, apr_pstrdup(r->pool, strerr)); pam_end(pamh, ret); return AUTH_DENIED; } apr_table_setn(r->subprocess_env, _REMOTE_USER_ENV_NAME, login); r->user = apr_pstrdup(r->pool, login); ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, r->server, "mod_authnz_pam: PAM authentication passed for user %s", login); pam_end(pamh, ret); return AUTH_GRANTED; }
AP_DECLARE(int) ap_update_child_status_from_indexes(int child_num, int thread_num, int status, request_rec *r) { int old_status; worker_score *ws; process_score *ps; if (child_num < 0) { return -1; } ws = &ap_scoreboard_image->servers[child_num][thread_num]; old_status = ws->status; ws->status = status; ps = &ap_scoreboard_image->parent[child_num]; if (status == SERVER_READY && old_status == SERVER_STARTING) { ws->thread_num = child_num * thread_limit + thread_num; ps->generation = ap_my_generation; } if (ap_extended_status) { ws->last_used = apr_time_now(); if (status == SERVER_READY || status == SERVER_DEAD) { /* * Reset individual counters */ if (status == SERVER_DEAD) { ws->my_access_count = 0L; ws->my_bytes_served = 0L; } ws->conn_count = 0; ws->conn_bytes = 0; } if (r) { conn_rec *c = r->connection; apr_cpystrn(ws->client, ap_get_remote_host(c, r->per_dir_config, REMOTE_NOLOOKUP, NULL), sizeof(ws->client)); copy_request(ws->request, sizeof(ws->request), r); apr_cpystrn(ws->vhost, r->server->server_hostname, sizeof(ws->vhost)); } } return old_status; }
static PyObject * req_get_remote_host(requestobject *self, PyObject *args) { int type = REMOTE_NAME; const char *host; if (! PyArg_ParseTuple(args, "|i", &type)) return NULL; host = ap_get_remote_host(self->request_rec->connection, self->request_rec->per_dir_config, type); if (! host) { Py_INCREF(Py_None); return Py_None; } else return PyString_FromString(host); }
static int find_allowdeny(request_rec *r, apr_array_header_t *a, int method, apr_time_t expire_time) { allowdeny *ap = (allowdeny *) a->elts; apr_int64_t mmask = (AP_METHOD_BIT << method); int i; int gothost = 0; const char *remotehost = NULL; char errmsg_buf[120]; apr_status_t rv; auth_remote_svr_conf *svr_conf = ap_get_module_config(r->server->module_config, &auth_remote_module); for (i = 0; i < a->nelts; ++i) { if (!(mmask & ap[i].limited)) { continue; } switch (ap[i].type) { case T_ENV: if (apr_table_get(r->subprocess_env, ap[i].x.from)) { return 1; } break; case T_NENV: if (!apr_table_get(r->subprocess_env, ap[i].x.from)) { return 1; } break; case T_ALL: return 1; case T_IP: if (apr_ipsubnet_test(ap[i].x.ip, r->connection->remote_addr)) { return 1; } break; case T_URL: #if APR_HAS_THREADS rv = apr_thread_mutex_lock (svr_conf->mutex); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "fail to obtain mutex: %s", errmsg_buf); break; } if (init_per_url_directive_data (r, &ap[i].x.remote_info) == -1) { rv = apr_thread_mutex_unlock (svr_conf->mutex); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "fail to release mutex: %s", errmsg_buf); break; } break; } rv = apr_thread_mutex_unlock (svr_conf->mutex); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "fail to release mutex: %s", errmsg_buf); break; } #else if (init_per_url_directive_data (&ap[i].x.remote_info) == -1) break; #endif if (ip_in_url_test (r, r->connection->remote_addr, &ap[i].x.remote_info, expire_time) == 1) { return 1; } break; case T_FILE: #if APR_HAS_THREADS rv = apr_thread_mutex_lock (svr_conf->mutex); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "fail to obtain mutex: %s", errmsg_buf); break; } if (init_per_local_file_directive_data (r, &ap[i].x.local_file_info) == -1) { rv = apr_thread_mutex_unlock (svr_conf->mutex); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "fail to release mutex: %s", errmsg_buf); break; } break; } rv = apr_thread_mutex_unlock (svr_conf->mutex); if (rv != APR_SUCCESS) { apr_strerror (rv, errmsg_buf, sizeof (errmsg_buf)); ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "fail to release mutex: %s", errmsg_buf); break; } #else if (init_per_local_file_directive_data (&ap[i].x.local_file_info) == -1) break; #endif if (ip_in_local_file_test (r, r->connection->remote_addr, &ap[i].x.local_file_info) == 1) { return 1; } break; case T_HOST: if (!gothost) { int remotehost_is_ip; remotehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_DOUBLE_REV, &remotehost_is_ip); if ((remotehost == NULL) || remotehost_is_ip) { gothost = 1; } else { gothost = 2; } } if ((gothost == 2) && in_domain(ap[i].x.from, remotehost)) { return 1; } break; case T_FAIL: /* do nothing? */ break; } } return 0; }
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; }
// Find the cookie and figure out what to do static int spot_cookie(request_rec *r) { cookietrack_settings_rec *dcfg = ap_get_module_config(r->per_dir_config, &cookietrack_module); const char *cookie_header; ap_regmatch_t regm[NUM_SUBS]; /* Do not run in subrequests */ if (!dcfg->enabled || r->main) { return DECLINED; } /* Is DNT set? */ const char *dnt_is_set = apr_table_get( r->headers_in, "DNT" ); _DEBUG && fprintf( stderr, "DNT: %s\n", dnt_is_set ); /* Do we already have a cookie? */ char *cur_cookie_value = NULL; if( (cookie_header = apr_table_get(r->headers_in, "Cookie")) ){ // this will match the FIRST occurance of the cookiename, not // subsequent ones. if( !ap_regexec(dcfg->regexp, cookie_header, NUM_SUBS, regm, 0) ) { /* Our regexp, * ^cookie_name=([^;]+)|;[ \t]+cookie_name=([^;]+) * only allows for $1 or $2 to be available. ($0 is always * filled with the entire matched expression, not just * the part in parentheses.) So just check for either one * and assign to cookieval if present. */ if( regm[1].rm_so != -1 ) { cur_cookie_value = ap_pregsub(r->pool, "$1", cookie_header, NUM_SUBS, regm); } if( regm[2].rm_so != -1 ) { cur_cookie_value = ap_pregsub(r->pool, "$2", cookie_header, NUM_SUBS, regm); } } } _DEBUG && fprintf( stderr, "Current Cookie: %s\n", cur_cookie_value ); /* XFF support inspired by this patch: http://www.mail-archive.com/[email protected]/msg17378.html And this implementation for scanning for remote ip: http://apache.wirebrain.de/lxr/source/modules/metadata/mod_remoteip.c?v=2.3-trunk#267 */ // Get the IP address of the originating request const char *rname = NULL; // Originating IP address char *xff = NULL; // X-Forwarded-For, or equivalent header type // Should we look at a header? if( xff = apr_table_get(r->headers_in, dcfg->cookie_ip_header) ) { // There might be multiple addresses in the header // Check if there's a comma in there somewhere // no comma, this is the address we can use if( (rname = strrchr(xff, ',')) == NULL ) { rname = xff; // whitespace/commas left, remove 'm } else { // move past the comma rname++; // and any whitespace we might find while( *rname == ' ' ) { rname++; } } // otherwise, get it from the remote host } else { rname = ap_get_remote_host( r->connection, r->per_dir_config, REMOTE_NAME, NULL ); } _DEBUG && fprintf( stderr, "Remote Address: %s\n", rname ); /* Determine the value of the cookie we're going to set: */ /* Make sure we have enough room here... */ char new_cookie_value[ _MAX_COOKIE_LENGTH ]; // dnt is set, and we care about that if( dnt_is_set && dcfg->comply_with_dnt ) { // you don't want us to set a cookie, alright then our work is done. if( !dcfg->set_dnt_cookie ) { return DECLINED; } char *dnt_value = dcfg->dnt_value; // you already ahve a cookie, but it might be whitelisted if( cur_cookie_value ) { // you might have whitelisted this value; let's check // Following tutorial code here again: // http://dev.ariel-networks.com/apr/apr-tutorial/html/apr-tutorial-19.html int i; for( i = 0; i < dcfg->dnt_exempt->nelts; i++ ) { _DEBUG && fprintf( stderr, "e: %d\n", i ); char *exempt = ((char **)dcfg->dnt_exempt->elts)[i]; //it's indeed whiteliested, we should use this value instead if( strcasecmp( cur_cookie_value, exempt ) == 0 ) { _DEBUG && fprintf( stderr, "Cookie %s is DNT exempt\n", cur_cookie_value ); dnt_value = exempt; } } } // dnt_value is a pointer, hence the sprintf sprintf( new_cookie_value, "%s", dnt_value ); // No DNT header, so we need a cookie value to set } else { // there already is a cookie set if( cur_cookie_value ) { // but it's set to the DNT cookie if( strcasecmp( cur_cookie_value, dcfg->dnt_value ) == 0 ) { // if we have some sort of library that's generating the // UID, call that with the cookie we would be setting if( _EXTERNAL_UID_FUNCTION ) { char ts[ _MAX_COOKIE_LENGTH ]; sprintf( ts, "%" APR_TIME_T_FMT, apr_time_now() ); gen_uid( new_cookie_value, ts, rname ); // otherwise, just set it } else { sprintf( new_cookie_value, "%s.%" APR_TIME_T_FMT, rname, apr_time_now() ); } // it's set to something reasonable - note we're still setting // a new cookie, even when there's no expires requested, because // we don't know if there's an expires on the /current/ cookie. // this could be added, but this seems to work for now. } else { // XXX we use a apr_pstrndup instead, so we can't overflow // the buffer if we get sent garbage // The return value is a sprintf( new_cookie_value, "%s", apr_pstrndup( r->pool, cur_cookie_value, _MAX_COOKIE_LENGTH ) ); } // it's either carbage, or not set; either way, // we need to generate a new one } else { // if we have some sort of library that's generating the // UID, call that with the cookie we would be setting if( _EXTERNAL_UID_FUNCTION ) { char ts[ _MAX_COOKIE_LENGTH ]; sprintf( ts, "%" APR_TIME_T_FMT, apr_time_now() ); gen_uid( new_cookie_value, ts, rname ); // otherwise, just set it } else { sprintf( new_cookie_value, "%s.%" APR_TIME_T_FMT, rname, apr_time_now() ); } } } _DEBUG && fprintf( stderr, "New cookie: %s\n", new_cookie_value ); /* Set the cookie in a note, for logging */ apr_table_setn(r->notes, dcfg->note_name, new_cookie_value); make_cookie(r, new_cookie_value, cur_cookie_value, (dnt_is_set && dcfg->comply_with_dnt) // should we use dnt expires? ); // We need to flush the stream for messages to appear right away. // Performing an fflush() in a production system is not good for // performance - don't do this for real. _DEBUG && fflush(stderr); return OK; /* We set our cookie */ }
// Generate the actual cookie void make_cookie(request_rec *r, char uid[], char cur_uid[], int use_dnt_expires) { // configuration cookietrack_settings_rec *dcfg; dcfg = ap_get_module_config(r->per_dir_config, &cookietrack_module); /* 1024 == hardcoded constant */ char cookiebuf[1024]; char *new_cookie; const char *rname = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL); /* XXX: hmm, this should really tie in with mod_unique_id */ apr_snprintf(cookiebuf, sizeof(cookiebuf), "%s", uid ); if (dcfg->expires) { /* Cookie with date; as strftime '%a, %d-%h-%y %H:%M:%S GMT' */ new_cookie = apr_psprintf(r->pool, "%s=%s; path=/", dcfg->cookie_name, cookiebuf); if ((dcfg->style == CT_UNSET) || (dcfg->style == CT_NETSCAPE)) { apr_time_exp_t tms; apr_time_exp_gmt(&tms, r->request_time + apr_time_from_sec(dcfg->expires)); // this sets a fixed expires in the future if( use_dnt_expires ) { new_cookie = apr_psprintf( r->pool, "%s; expires=%s", new_cookie, dcfg->dnt_expires ); // use the dynamic one } else { new_cookie = apr_psprintf( r->pool, "%s; expires=%s, %.2d-%s-%.2d %.2d:%.2d:%.2d GMT", new_cookie, apr_day_snames[tms.tm_wday], tms.tm_mday, apr_month_snames[tms.tm_mon], tms.tm_year % 100, tms.tm_hour, tms.tm_min, tms.tm_sec ); } } else { int expires = 0; // use a static expires date in the future if( use_dnt_expires ) { time_t t; time( &t ); expires = dcfg->dnt_max_age - t; // use the dynamic one } else { expires = dcfg->expires; } _DEBUG && fprintf( stderr, "Expires = %d\n", expires ); new_cookie = apr_psprintf( r->pool, "%s; max-age=%d", new_cookie, expires ); } } else { new_cookie = apr_psprintf(r->pool, "%s=%s; path=/", dcfg->cookie_name, cookiebuf); } if (dcfg->cookie_domain != NULL) { new_cookie = apr_pstrcat(r->pool, new_cookie, "; domain=", dcfg->cookie_domain, (dcfg->style == CT_COOKIE2 ? "; version=1" : ""), NULL); } // r->err_headers_out also honors non-2xx responses and // internal redirects. See the patch here: // http://svn.apache.org/viewvc?view=revision&revision=1154620 apr_table_addn( r->err_headers_out, (dcfg->style == CT_COOKIE2 ? "Set-Cookie2" : "Set-Cookie"), new_cookie ); // we also set it on the INCOMING cookie header, so the app can // Just Use It without worrying. Only do so if we don't already // have an incoming cookie value, or it will send 2 cookies with // the same name, with both the old and new value :( if( !cur_uid ) { apr_table_addn( r->headers_in, "Cookie", new_cookie ); } // Set headers? We set both incoming AND outgoing: if( dcfg->send_header ) { // incoming apr_table_addn( r->headers_in, dcfg->header_name, apr_pstrdup(r->pool, uid) ); // outgoing apr_table_addn( r->err_headers_out, dcfg->header_name, apr_pstrdup(r->pool, uid) ); } // set a note, so we can capture it in the logs // this expects chars, and apr_pstrdup will make sure any char stays // in scope for the function. If not, it ends up being empty. apr_table_setn( r->notes, dcfg->note_name, apr_pstrdup(r->pool, uid) ); }
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); } }
/* Run an external authentication program using the given method for passing * in the data. The login name is always passed in. Dataname is "GROUP" or * "PASS" and data is the group list or password being checked. To launch * a detached daemon, run this with extmethod=NULL. * * If the authenticator was run, we return the numeric code from the * authenticator, normally 0 if the login was valid, some small positive * number if not. If we were not able to run the authenticator, we log * an error message and return a numeric error code: * * -1 Could not execute authenticator, usually a path or permission problem * -2 The external authenticator crashed or was killed. * -3 Could not create process attribute structure * -4 apr_proc_wait() did not return a status code. Should never happen. * -5 apr_proc_wait() returned before child finished. Should never happen. */ static int exec_external(const char *extpath, const char *extmethod, const request_rec *r, const char *dataname, const char *data) { conn_rec *c= r->connection; apr_pool_t *p= r->pool; int isdaemon, usecheck= 0, usepipeout= 0, usepipein= 0; apr_procattr_t *procattr; apr_proc_t proc; apr_status_t rc= APR_SUCCESS; char *child_env[12]; char *child_arg[MAX_ARG+2]; const char *t; int i, status= -4; apr_exit_why_e why= APR_PROC_EXIT; apr_sigfunc_t *sigchld; /* Set various flags based on the execution method */ isdaemon= (extmethod == NULL); if (!isdaemon) { usecheck= extmethod && !strcasecmp(extmethod, "checkpassword"); usepipeout= usecheck || (extmethod && !strcasecmp(extmethod, "pipes")); usepipein= usepipeout || (extmethod && !strcasecmp(extmethod, "pipe")); } /* Create the environment for the child. Daemons don't get these, they * just inherit apache's environment variables. */ if (!isdaemon) { const char *cookie, *host, *remote_host; authnz_external_dir_config_rec *dir= (authnz_external_dir_config_rec *) ap_get_module_config(r->per_dir_config, &authnz_external_module); i= 0; if (!usepipein) { /* Put user name and password/group into environment */ child_env[i++]= apr_pstrcat(p, ENV_USER"=", r->user, NULL); child_env[i++]= apr_pstrcat(p, dataname, "=", data, NULL); } child_env[i++]= apr_pstrcat(p, "PATH=", getenv("PATH"), NULL); child_env[i++]= apr_pstrcat(p, "AUTHTYPE=", dataname, NULL); remote_host= ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST,NULL); if (remote_host != NULL) child_env[i++]= apr_pstrcat(p, ENV_HOST"=", remote_host,NULL); if (r->useragent_ip) child_env[i++]= apr_pstrcat(p, ENV_IP"=", r->useragent_ip, NULL); if (r->uri) child_env[i++]= apr_pstrcat(p, ENV_URI"=", r->uri, NULL); if ((host= apr_table_get(r->headers_in, "Host")) != NULL) child_env[i++]= apr_pstrcat(p, ENV_HTTP_HOST"=", host, NULL); if (dir->context) child_env[i++]= apr_pstrcat(r->pool, ENV_CONTEXT"=", dir->context, NULL); #ifdef ENV_COOKIE if ((cookie= apr_table_get(r->headers_in, "Cookie")) != NULL) child_env[i++]= apr_pstrcat(p, ENV_COOKIE"=", cookie, NULL); #endif /* NOTE: If you add environment variables, * remember to increase the size of the child_env[] array */ /* End of environment */ child_env[i]= NULL; } /* Construct argument array */ for (t= extpath, i=0; *t != '\0' && (i <= MAX_ARG + 1); child_arg[i++]= ap_getword_white(p, &t)) {} child_arg[i]= NULL; /* Create the process attribute structure describing the script we * want to run using the Thread/Process functions from the Apache * portable runtime library. */ if (((rc= apr_procattr_create(&procattr, p)) != APR_SUCCESS) || /* should we create pipes to stdin, stdout and stderr? */ ((rc= apr_procattr_io_set(procattr, (usepipein && !usecheck) ? APR_FULL_BLOCK : APR_NO_PIPE, usepipeout ? APR_FULL_BLOCK : APR_NO_PIPE, (usepipein && usecheck) ? APR_FULL_BLOCK : APR_NO_PIPE)) != APR_SUCCESS ) || /* will give full path of program and make a new environment */ ((rc= apr_procattr_cmdtype_set(procattr, isdaemon ? APR_PROGRAM_ENV : APR_PROGRAM)) != APR_SUCCESS) || /* detach the child only if it is a daemon */ ((rc= apr_procattr_detach_set(procattr, isdaemon)) != APR_SUCCESS) || /* function to call if child has error after fork, before exec */ ((rc= apr_procattr_child_errfn_set(procattr, extchilderr) != APR_SUCCESS))) { /* Failed. Probably never happens. */ ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "could not set child process attributes"); return -3; } /* Sometimes other modules wil mess up sigchild. Need to fix it for * the wait call to work correctly. */ sigchld= apr_signal(SIGCHLD,SIG_DFL); /* Start the child process */ rc= apr_proc_create(&proc, child_arg[0], (const char * const *)child_arg, (const char * const *)child_env, procattr, p); if (rc != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "Could not run external authenticator: %d: %s", rc, child_arg[0]); return -1; } if (isdaemon) return 0; apr_pool_note_subprocess(p, &proc, APR_KILL_AFTER_TIMEOUT); if (usepipein) { /* Select appropriate pipe to write to */ apr_file_t *pipe= (usecheck ? proc.err : proc.in); /* Send the user */ apr_file_write_full(pipe, r->user, strlen(r->user), NULL); apr_file_putc(usecheck ? '\0' : '\n', pipe); /* Send the password */ apr_file_write_full(pipe, data, strlen(data), NULL); apr_file_putc(usecheck ? '\0' : '\n', pipe); /* Send the uri/path */ apr_file_write_full(pipe, r->uri, strlen(r->uri), NULL); apr_file_putc(usecheck ? '\0' : '\n', pipe); /* Send dummy timestamp for checkpassword */ if (usecheck) apr_file_write_full(pipe, "0", 2, NULL); /* Close the file */ apr_file_close(pipe); } /* Wait for the child process to terminate, and get status */ rc= apr_proc_wait(&proc,&status,&why,APR_WAIT); /* Restore sigchild to whatever it was before we reset it */ apr_signal(SIGCHLD,sigchld); if (!APR_STATUS_IS_CHILD_DONE(rc)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rc, r, "Could not get status from child process"); return -5; } if (!APR_PROC_CHECK_EXIT(why)) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "External authenticator died on signal %d",status); return -2; } return status; }
/** * Writes request parameters to srun. */ static void write_env(stream_t *s, request_rec *r, char *session_id) { char buf[4096]; int ch; int i; conn_rec *c = r->connection; const char *host; int port; int is_sub_request = 1; char *uri; /* * is_sub_request is always true, since we can't detect mod_rewrite * and mod_rewrite doesn't change the unparsed_uri. */ if (is_sub_request) uri = r->uri; /* for mod_rewrite */ else uri = r->unparsed_uri; /* #937 */ for (i = 0; (ch = uri[i]) && ch != '?' && i + 1 < sizeof(buf); i++) buf[i] = ch; if (session_id) { buf[i++] = *s->config->session_url_prefix; for (session_id++; *session_id && i + 1 < sizeof(buf); i++) buf[i] = *session_id++; } buf[i] = 0; cse_write_string(s, HMUX_URL, buf); cse_write_string(s, HMUX_METHOD, r->method); if (*s->config->alt_session_url_prefix && r->request_config) { char *suburi = ap_get_module_config(r->request_config, &caucho_module); if (suburi) uri = suburi; } cse_write_string(s, CSE_PROTOCOL, r->protocol); if (r->args) cse_write_string(s, CSE_QUERY_STRING, r->args); /* Gets the server name */ host = ap_get_server_name(r); port = ap_get_server_port(r); cse_write_string(s, HMUX_SERVER_NAME, host); cse_write_string(s, CSE_SERVER_PORT, ap_psprintf(r->pool, "%u", port)); host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST); if (host) cse_write_string(s, CSE_REMOTE_HOST, host); else cse_write_string(s, CSE_REMOTE_HOST, c->remote_ip); cse_write_string(s, CSE_REMOTE_ADDR, c->remote_ip); cse_write_string(s, CSE_REMOTE_PORT, ap_psprintf(r->pool, "%d", ntohs(c->remote_addr.sin_port))); if (c->user) cse_write_string(s, CSE_REMOTE_USER, c->user); if (c->ap_auth_type) cse_write_string(s, CSE_AUTH_TYPE, c->ap_auth_type); }
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); } }
static const char *log_remote_host(request_rec *r, char *a) { return ap_escape_logitem(r->pool, ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME)); }
static int ipp_handler(request_rec *r) { papi_attribute_t **request = NULL, **response = NULL; IPPListenerConfig *config; papi_status_t status; int ret; /* Really, IPP is all POST requests */ if (r->method_number != M_POST) return (DECLINED); #ifndef APACHE2 /* * An IPP request must have a MIME type of "application/ipp" * (RFC-2910, Section 4, page 19). If it doesn't match this * MIME type, we should decline the request and let someone else * try and handle it. */ if (r->headers_in != NULL) { char *mime_type = (char *)ap_table_get(r->headers_in, "Content-Type"); if ((mime_type == NULL) || (strcasecmp(mime_type, "application/ipp") != 0)) return (DECLINED); } #endif /* CHUNKED_DECHUNK might not work right for IPP? */ if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK) return (ret); if (!ap_should_client_block(r)) return (HTTP_INTERNAL_SERVER_ERROR); #ifndef APACHE2 ap_soft_timeout("ipp_module: read/reply request ", r); #endif /* read the IPP request off the network */ status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST); if (status != PAPI_OK) _log_rerror(APLOG_MARK, APLOG_ERR, r, "read failed: %s\n", papiStatusString(status)); #ifdef DEBUG papiAttributeListPrint(stderr, request, "request (%d) ", getpid()); #endif (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "originating-host", (char *) #ifdef APACHE2 ap_get_remote_host (r->connection, r->per_dir_config, REMOTE_NAME, NULL)); #else ap_get_remote_host (r->connection, r->per_dir_config, REMOTE_NAME)); #endif (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, "uri-port", ap_get_server_port(r)); if (r->headers_in != NULL) { char *host = (char *)ap_table_get(r->headers_in, "Host"); if ((host == NULL) || (host[0] == '\0')) host = (char *)ap_get_server_name(r); (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "uri-host", host); } (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "uri-path", r->uri); config = ap_get_module_config(r->per_dir_config, &ipp_module); if (config != NULL) { (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, "conformance", config->conformance); (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL, "operations", config->operations); if (config->default_user != NULL) (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "default-user", config->default_user); if (config->default_svc != NULL) (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL, "default-service", config->default_svc); } /* * For Trusted Solaris, pass the fd number of the socket connection * to the backend so the it can be forwarded to the backend print * service to retrieve the sensativity label off of a multi-level * port. */ (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL, "peer-socket", ap_bfileno(r->connection->client, B_RD)); /* process the request */ status = ipp_process_request(request, &response, read_data, r); if (status != PAPI_OK) { errno = 0; _log_rerror(APLOG_MARK, APLOG_ERR, r, "request failed: %s\n", papiStatusString(status)); discard_data(r); } #ifdef DEBUG fprintf(stderr, "processing result: %s\n", papiStatusString(status)); papiAttributeListPrint(stderr, response, "response (%d) ", getpid()); #endif /* * If the client is using chunking and we have not yet received the * final "0" sized chunk, we need to discard any data that may * remain in the post request. */ if ((r->read_chunked != 0) && (ap_table_get(r->headers_in, "Content-Length") == NULL)) discard_data(r); /* write an IPP response back to the network */ r->content_type = "application/ipp"; #ifndef APACHE2 ap_send_http_header(r); #endif status = ipp_write_message(write_data, r, response); if (status != PAPI_OK) _log_rerror(APLOG_MARK, APLOG_ERR, r, "write failed: %s\n", papiStatusString(status)); #ifdef DEBUG fprintf(stderr, "write result: %s\n", papiStatusString(status)); fflush(stderr); #endif papiAttributeListFree(request); papiAttributeListFree(response); #ifndef APACHE2 ap_kill_timeout(r); if (ap_rflush(r) < 0) _log_rerror(APLOG_MARK, APLOG_ERR, r, "flush failed, response may not have been sent"); #endif return (OK); }
/* Routine to perform the actual construction and execution of the relevant * INSERT statements. */ static int log_sql_transaction(request_rec *orig) { char **ptrptr, **ptrptr2; logsql_state *cls = ap_get_module_config(orig->server->module_config, &log_sql_module); const char *access_query; request_rec *r; const char *transfer_tablename = cls->transfer_table_name; const char *notes_tablename = cls->notes_table_name; const char *hout_tablename = cls->hout_table_name; const char *hin_tablename = cls->hin_table_name; const char *cookie_tablename = cls->cookie_table_name; if (global_config.driver == NULL) { return OK; } /* We handle mass virtual hosting differently. Dynamically determine the name * of the table from the virtual server's name, and flag it for creation. */ if (global_config.massvirtual) { /* TODO: Make these configurable? */ char *access_base = "access_"; char *notes_base = "notes_"; char *hout_base = "headout_"; char *hin_base = "headin_"; char *cookie_base = "cookies_"; /* Determine the hostname and convert it to all lower-case; */ char *servername = apr_pstrdup(orig->pool,(char *)ap_get_server_name(orig)); char *p=servername; while (*p) { *p = apr_tolower(*p); if (*p == '.') *p = '_'; if (*p == '-') *p = '_'; ++p; } /* Find memory long enough to hold the table name + \0. */ transfer_tablename = apr_pstrcat(orig->pool, access_base, servername, NULL); notes_tablename = apr_pstrcat(orig->pool, notes_base, servername, NULL); hin_tablename = apr_pstrcat(orig->pool, hin_base, servername, NULL); hout_tablename = apr_pstrcat(orig->pool, hout_base, servername, NULL); cookie_tablename = apr_pstrcat(orig->pool, cookie_base, servername, NULL); /* Tell this virtual server its transfer table name, and * turn on create_tables, which is implied by massvirtual. */ global_config.createtables = 1; } /* Do we have enough info to log? */ if (!transfer_tablename) { return DECLINED; } else { const char *thehost; const char *theitem; char *fields = "", *values = ""; char *itemsets = ""; char *note_query = NULL; char *hin_query = NULL; char *hout_query = NULL; char *cookie_query = NULL; const char *unique_id; const char *formatted_item; int i,length; int proceed; for (r = orig; r->next; r = r->next) { continue; } /* The following is a stolen upsetting mess of pointers, I'm sorry. * Anyone with the motiviation and/or the time should feel free * to make this cleaner. :) */ ptrptr2 = (char **) (cls->transfer_accept_list->elts + (cls->transfer_accept_list->nelts * cls->transfer_accept_list->elt_size)); /* Go through each element of the accept list and compare it to the * request_uri. If we don't get a match, return without logging */ if ((r->uri) && (cls->transfer_accept_list->nelts)) { proceed = 0; for (ptrptr = (char **) cls->transfer_accept_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_accept_list->elt_size)) if (ap_strstr(r->uri, *ptrptr)) { proceed = 1; break; } if (!proceed) return OK; } /* Go through each element of the ignore list and compare it to the * request_uri. If we get a match, return without logging */ ptrptr2 = (char **) (cls->transfer_ignore_list->elts + (cls->transfer_ignore_list->nelts * cls->transfer_ignore_list->elt_size)); if (r->uri) { for (ptrptr = (char **) cls->transfer_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->transfer_ignore_list->elt_size)) if (ap_strstr(r->uri, *ptrptr)) { return OK; } } /* Go through each element of the ignore list and compare it to the * remote host. If we get a match, return without logging */ ptrptr2 = (char **) (cls->remhost_ignore_list->elts + (cls->remhost_ignore_list->nelts * cls->remhost_ignore_list->elt_size)); thehost = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, NULL); if (thehost) { for (ptrptr = (char **) cls->remhost_ignore_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->remhost_ignore_list->elt_size)) if (ap_strstr(thehost, *ptrptr)) { return OK; } } /* Iterate through the format characters and set up the INSERT string according to * what the user has configured. */ length = strlen(cls->transfer_log_format); for (i = 0; i<length; i++) { logsql_item *item = cls->parsed_log_format[i]; if (item==NULL) { log_error(APLOG_MARK, APLOG_ERR, 0, orig->server, "Log Format '%c' unknown",cls->transfer_log_format[i]); continue; } /* Yes, this key is one of the configured keys. * Call the key's function and put the returned value into 'formatted_item' */ formatted_item = item->func(item->want_orig_default ? orig : r, ""); /* Massage 'formatted_item' for proper SQL eligibility... */ if (!formatted_item) { formatted_item = ""; } else if (formatted_item[0] == '-' && formatted_item[1] == '\0' && !item->string_contents) { /* If apache tried to log a '-' character for a numeric field, convert that to a zero * because the database expects a numeral and will reject the '-' character. */ formatted_item = "0"; } /* Append the fieldname and value-to-insert to the appropriate strings, quoting stringvals with ' as appropriate */ fields = apr_pstrcat(r->pool, fields, (i ? "," : ""), item->sql_field_name, NULL); values = apr_pstrcat(r->pool, values, (i ? "," : ""), global_config.driver->escape(formatted_item, r->pool,&global_config.db), NULL); } /* Work through the list of notes defined by LogSQLWhichNotes */ i = 0; unique_id = extract_unique_id(r, ""); ptrptr2 = (char **) (cls->notes_list->elts + (cls->notes_list->nelts * cls->notes_list->elt_size)); for (ptrptr = (char **) cls->notes_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->notes_list->elt_size)) { /* If the specified note (*ptrptr) exists for the current request... */ if ((theitem = apr_table_get(r->notes, *ptrptr))) { itemsets = apr_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "(", global_config.driver->escape(unique_id, r->pool, &global_config.db), ",", global_config.driver->escape(*ptrptr, r->pool,&global_config.db), ",", global_config.driver->escape(theitem, r->pool,&global_config.db), ")", NULL); i++; } } if ( *itemsets != '\0' ) { note_query = apr_psprintf(r->pool, "insert %s into %s (id, item, val) values %s", /*global_config.insertdelayed?"delayed":*/"", notes_tablename, itemsets); log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: note string: %s", note_query); } /* Work through the list of headers-out defined by LogSQLWhichHeadersOut*/ i = 0; itemsets = ""; ptrptr2 = (char **) (cls->hout_list->elts + (cls->hout_list->nelts * cls->hout_list->elt_size)); for (ptrptr = (char **) cls->hout_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hout_list->elt_size)) { /* If the specified header (*ptrptr) exists for the current request... */ if ((theitem = apr_table_get(r->headers_out, *ptrptr))) { itemsets = apr_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "(", global_config.driver->escape(unique_id, r->pool, &global_config.db), ",", global_config.driver->escape(*ptrptr, r->pool,&global_config.db), ",", global_config.driver->escape(theitem, r->pool,&global_config.db), ")", NULL); i++; } } if ( *itemsets != '\0' ) { hout_query = apr_psprintf(r->pool, "insert %s into %s (id, item, val) values %s", /*global_config.insertdelayed?"delayed":*/"", hout_tablename, itemsets); log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: header_out string: %s", hout_query); } /* Work through the list of headers-in defined by LogSQLWhichHeadersIn */ i = 0; itemsets = ""; ptrptr2 = (char **) (cls->hin_list->elts + (cls->hin_list->nelts * cls->hin_list->elt_size)); for (ptrptr = (char **) cls->hin_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->hin_list->elt_size)) { /* If the specified header (*ptrptr) exists for the current request... */ if ((theitem = apr_table_get(r->headers_in, *ptrptr))) { itemsets = apr_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "(", global_config.driver->escape(unique_id, r->pool, &global_config.db), ",", global_config.driver->escape(*ptrptr, r->pool,&global_config.db), ",", global_config.driver->escape(theitem, r->pool,&global_config.db), ")", NULL); i++; } } if ( *itemsets != '\0' ) { hin_query = apr_psprintf(r->pool, "insert %s into %s (id, item, val) values %s", /*global_config.insertdelayed?"delayed":*/"", hin_tablename, itemsets); log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: header_in string: %s", hin_query); } /* Work through the list of cookies defined by LogSQLWhichCookies */ i = 0; itemsets = ""; ptrptr2 = (char **) (cls->cookie_list->elts + (cls->cookie_list->nelts * cls->cookie_list->elt_size)); for (ptrptr = (char **) cls->cookie_list->elts; ptrptr < ptrptr2; ptrptr = (char **) ((char *) ptrptr + cls->cookie_list->elt_size)) { /* If the specified cookie (*ptrptr) exists for the current request... */ if ( strncmp((theitem = extract_specific_cookie(r, *ptrptr)), "-", 1) ) { itemsets = apr_pstrcat(r->pool, itemsets, (i > 0 ? "," : ""), "(", global_config.driver->escape(unique_id, r->pool, &global_config.db), ",", global_config.driver->escape(*ptrptr, r->pool,&global_config.db), ",", global_config.driver->escape(theitem, r->pool,&global_config.db), ")", NULL); i++; } } if ( *itemsets != '\0' ) { cookie_query = apr_psprintf(r->pool, "insert %s into %s (id, item, val) values %s", /*global_config.insertdelayed?"delayed":*/"", cookie_tablename, itemsets); log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: cookie string: %s", cookie_query); } /* Set up the actual INSERT statement */ access_query = apr_psprintf(r->pool, "insert %s into %s (%s) values (%s)", /*global_config.insertdelayed?"delayed":*/"", transfer_tablename, fields, values); log_error(APLOG_MARK,APLOG_DEBUG,0, r->server,"mod_log_sql: access string: %s", access_query); /* If the person activated force-preserve, go ahead and push all the entries * into the preserve file, then return. */ if (global_config.forcepreserve) { log_error(APLOG_MARK,APLOG_DEBUG,0, orig->server,"mod_log_sql: preservation forced"); preserve_entry(orig, access_query); if ( note_query != NULL ) preserve_entry(orig, note_query); if ( hin_query != NULL ) preserve_entry(orig, hin_query); if ( hout_query != NULL ) preserve_entry(orig, hout_query); if ( cookie_query != NULL ) preserve_entry(orig, cookie_query); return OK; } /* How's our mysql link integrity? */ if (!global_config.db.connected) { if (!global_config.forcepreserve) { /* Make a try to establish the link */ log_sql_opendb_link(r->server); } if (!global_config.db.connected) { /* Unable to re-establish a DB link, so assume that it's really * gone and send the entry to the preserve file instead. * This short-circuits safe_sql_query() during a db outage and therefore * we don't keep logging the db error over and over. */ preserve_entry(orig, access_query); if ( note_query != NULL ) preserve_entry(orig, note_query); if ( hin_query != NULL ) preserve_entry(orig, hin_query); if ( hout_query != NULL ) preserve_entry(orig, hout_query); if ( cookie_query != NULL ) preserve_entry(orig, cookie_query); return OK; } else { /* Whew, we got the DB link back */ log_error(APLOG_MARK,APLOG_NOTICE,0, orig->server,"mod_log_sql: child established database connection"); } } /* ---> So as of here we have a non-null value of mysql_log. <--- */ /* ---> i.e. we have a good MySQL connection. <--- */ /* Make the access-table insert */ safe_sql_insert(orig,LOGSQL_TABLE_ACCESS,transfer_tablename,access_query); /* Log the optional notes, headers, etc. */ if (note_query) safe_sql_insert(orig, LOGSQL_TABLE_NOTES,notes_tablename,note_query); if (hout_query) safe_sql_insert(orig, LOGSQL_TABLE_HEADERSOUT,hout_tablename,hout_query); if (hin_query) safe_sql_insert(orig, LOGSQL_TABLE_HEADERSIN,hin_tablename,hin_query); if (cookie_query) safe_sql_insert(orig, LOGSQL_TABLE_COOKIES,cookie_tablename,cookie_query); return OK; } }
API_EXPORT(void) ap_add_common_vars(request_rec *r) { table *e; server_rec *s = r->server; conn_rec *c = r->connection; const char *rem_logname; char *env_path; #if defined(WIN32) || defined(OS2) char *env_temp; #endif const char *host; array_header *hdrs_arr = ap_table_elts(r->headers_in); table_entry *hdrs = (table_entry *) hdrs_arr->elts; int i; char servbuf[NI_MAXSERV]; /* use a temporary table which we'll overlap onto * r->subprocess_env later */ e = ap_make_table(r->pool, 25 + hdrs_arr->nelts); /* First, add environment vars from headers... this is as per * CGI specs, though other sorts of scripting interfaces see * the same vars... */ for (i = 0; i < hdrs_arr->nelts; ++i) { if (!hdrs[i].key) { continue; } /* A few headers are special cased --- Authorization to prevent * rogue scripts from capturing passwords; content-type and -length * for no particular reason. */ if (!strcasecmp(hdrs[i].key, "Content-type")) { ap_table_addn(e, "CONTENT_TYPE", hdrs[i].val); } else if (!strcasecmp(hdrs[i].key, "Content-length")) { ap_table_addn(e, "CONTENT_LENGTH", hdrs[i].val); } /* * You really don't want to disable this check, since it leaves you * wide open to CGIs stealing passwords and people viewing them * in the environment with "ps -e". But, if you must... */ #ifndef SECURITY_HOLE_PASS_AUTHORIZATION else if (!strcasecmp(hdrs[i].key, "Authorization") || !strcasecmp(hdrs[i].key, "Proxy-Authorization")) { continue; } #endif else { ap_table_addn(e, http2env(r->pool, hdrs[i].key), hdrs[i].val); } } if (!(env_path = ap_pstrdup(r->pool, getenv("PATH")))) { env_path = DEFAULT_PATH; } #ifdef WIN32 if (env_temp = getenv("SystemRoot")) { ap_table_addn(e, "SystemRoot", env_temp); } if (env_temp = getenv("COMSPEC")) { ap_table_addn(e, "COMSPEC", env_temp); } if (env_temp = getenv("WINDIR")) { ap_table_addn(e, "WINDIR", env_temp); } #endif #ifdef OS2 if ((env_temp = getenv("COMSPEC")) != NULL) { ap_table_addn(e, "COMSPEC", env_temp); } if ((env_temp = getenv("ETC")) != NULL) { ap_table_addn(e, "ETC", env_temp); } if ((env_temp = getenv("DPATH")) != NULL) { ap_table_addn(e, "DPATH", env_temp); } if ((env_temp = getenv("PERLLIB_PREFIX")) != NULL) { ap_table_addn(e, "PERLLIB_PREFIX", env_temp); } #endif ap_table_addn(e, "PATH", env_path); ap_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r)); ap_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version()); ap_table_addn(e, "SERVER_NAME", ap_escape_html(r->pool,ap_get_server_name(r))); ap_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /* Apache */ ap_table_addn(e, "SERVER_PORT", ap_psprintf(r->pool, "%u", ap_get_server_port(r))); host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST); if (host) { ap_table_addn(e, "REMOTE_HOST", host); } ap_table_addn(e, "REMOTE_ADDR", c->remote_ip); ap_table_addn(e, "DOCUMENT_ROOT", ap_document_root(r)); /* Apache */ ap_table_addn(e, "SERVER_ADMIN", s->server_admin); /* Apache */ ap_table_addn(e, "SCRIPT_FILENAME", r->filename); /* Apache */ servbuf[0] = '\0'; if (!getnameinfo((struct sockaddr *)&c->remote_addr, #ifndef HAVE_SOCKADDR_LEN SA_LEN((struct sockaddr *)&c->remote_addr), #else c->remote_addr.ss_len, #endif NULL, 0, servbuf, sizeof(servbuf), NI_NUMERICSERV)){ ap_table_addn(e, "REMOTE_PORT", ap_pstrdup(r->pool, servbuf)); } if (c->user) { ap_table_addn(e, "REMOTE_USER", c->user); } if (c->ap_auth_type) { ap_table_addn(e, "AUTH_TYPE", c->ap_auth_type); } rem_logname = ap_get_remote_logname(r); if (rem_logname) { ap_table_addn(e, "REMOTE_IDENT", ap_pstrdup(r->pool, rem_logname)); } /* Apache custom error responses. If we have redirected set two new vars */ if (r->prev) { if (r->prev->args) { ap_table_addn(e, "REDIRECT_QUERY_STRING", r->prev->args); } if (r->prev->uri) { ap_table_addn(e, "REDIRECT_URL", r->prev->uri); } } ap_overlap_tables(r->subprocess_env, e, AP_OVERLAP_TABLES_SET); }
static int hostprotect_handler(request_rec *r) { char *client_ip; int is_ip = 0; int rbl_status = 0; if(hp.enabled == 1) { client_ip = ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_NAME, &is_ip); if(is_ip) { /* purging */ if(!strcmp(client_ip, hp.purger) && !strcmp(r->method, "DELETE")) { char *ip_to_purge = apr_table_get(r->headers_in, "X-Purge-From-BL"); if(ip_to_purge == NULL) return DECLINED; int purge_status = purge_shm(ip_to_purge); if(purge_status == PURGE_OK) { int cache_to_clear = clear_shm(hp.expire); if(cache_to_clear != CLEAR_ERR) { if(hp.debug) ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "%s: PURGED %d ITEMS FROM CACHE, EXPIRE TIME %d", MODULE_NAME, cache_to_clear, hp.expire); } if(hp.debug) ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "%s: PURGED FROM CACHE %s", MODULE_NAME, ip_to_purge); } return DECLINED; } /* cache search */ int cache_hit = search_shm(client_ip); /* cache hit */ if(cache_hit > 1) { /* clear expired cache on random HIT request */ if(!(r->request_time % 256)) { int cache_to_clear = clear_shm(hp.expire); if(cache_to_clear != CLEAR_ERR) { if(hp.debug) ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "%s: PURGED %d ITEMS FROM CACHE, EXPIRE TIME %d", MODULE_NAME, cache_to_clear, hp.expire); } } if(hp.debug) ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "%s: CACHE HIT FOR %s (counter %d)", MODULE_NAME, client_ip, cache_hit); update_shm(client_ip); rbl_status = 1; goto err_redirect; } else { /* cache miss */ check_rbl(client_ip, hp.resolver, &rbl_status, r); if(hp.debug) ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "%s: Checking for blacklist %s | status %d", MODULE_NAME, client_ip, rbl_status); err_redirect: /* blacklisted */ if(rbl_status) { update_shm(client_ip); ap_set_content_type(r, "text/html"); ap_rprintf(r, "<html><head><title>Your IP is blacklisted in bl.hostprotect.net - redirecting..</title><META http-equiv='refresh' content='1;URL=http://www.hostprotect.net/'></head><body bgcolor='#ffffff'><center>Your IP is blacklisted in bl.hostprotect.net. You will be redirected automatically in 3 seconds.</center></body></html>"); return OK; } } } } return DECLINED; }
static int authenticate_token(request_rec *r) { const char *usertoken, *timestamp, *path, *remoteip; unsigned char digest[APR_MD5_DIGESTSIZE]; char token[APR_MD5_DIGESTSIZE * 2]; auth_token_config_rec *conf; apr_md5_ctx_t context; conf = ap_get_module_config(r->per_dir_config, &auth_token_module); /* Get the remote IP , forcing to get an IP instead DNS record*/ if (conf->checkip) { remoteip = ap_get_remote_host(r->connection, NULL, REMOTE_NAME, NULL); if(NULL == remoteip) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "mod_auth_token: request from ip FAILED." ); return DECLINED; } ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "mod_auth_token: request from ip %s", remoteip ); } /* check if the request uri is to be protected */ if (conf->prefix == NULL || strncmp(r->uri, conf->prefix, conf->prefix_len)) { return DECLINED; } /* <prefix> <32-byte-token> "/" <8-byte-timestamp> "/" */ if (strlen(r->uri) < conf->prefix_len + 32 + 1 + 8 + 1) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "mod_auth_token: malformed or nonexistent token"); return HTTP_UNAUTHORIZED; } /* mark token, timestamp and relative path components */ usertoken = r->uri + conf->prefix_len; timestamp = r->uri + conf->prefix_len + 32 + 1; path = r->uri + conf->prefix_len + 32 + 1 + 8; /* check if token has expired */ if ((unsigned int)apr_time_sec(apr_time_now()) > auth_token_hex2sec(timestamp) + conf->timeout) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "mod_auth_token: token expired at %u, now is %u", auth_token_hex2sec(timestamp) + conf->timeout, (unsigned int)apr_time_sec(apr_time_now())); return HTTP_GONE; } /* create md5 token of secret + path + timestamp */ apr_md5_init(&context); apr_md5_update(&context, (unsigned char *) conf->secret, strlen(conf->secret)); apr_md5_update(&context, (unsigned char *) path, strlen(path)); apr_md5_update(&context, (unsigned char *) timestamp, 8); if (conf->checkip) apr_md5_update(&context, (unsigned char *) remoteip, strlen(remoteip)); apr_md5_final(digest, &context); /* compare hex encoded token and user provided token */ auth_token_bin2hex(token, (const char *)digest, APR_MD5_DIGESTSIZE); if (strncasecmp(token, usertoken, APR_MD5_DIGESTSIZE * 2) == 0) { /* remove token and timestamp from uri */ memmove(r->uri + conf->prefix_len - 1, path, strlen(path) + 1); r->filename = apr_pstrdup(r->pool, r->uri); /* allow other modules to run their hooks */ return DECLINED; } ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "mod_auth_token: failed token auth (got '%s', expected '%s', uri '%s')", apr_pstrndup(r->pool, usertoken, 32), apr_pstrndup(r->pool, token, 32), r->uri); return HTTP_FORBIDDEN; }