|
Packit Service |
384592 |
/*
|
|
Packit Service |
384592 |
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
|
Packit Service |
384592 |
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* You may not use this file except in compliance with
|
|
Packit Service |
384592 |
* the License. You may obtain a copy of the License at
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* If any of the files related to licensing are missing or if you have any
|
|
Packit Service |
384592 |
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
|
Packit Service |
384592 |
* directly using the email address security@modsecurity.org.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#include "modsecurity.h"
|
|
Packit Service |
384592 |
#include "apache2.h"
|
|
Packit Service |
384592 |
#include "http_core.h"
|
|
Packit Service |
384592 |
#include "util_script.h"
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Sends a brigade with an error bucket down the filter chain.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
apr_status_t send_error_bucket(modsec_rec *msr, ap_filter_t *f, int status) {
|
|
Packit Service |
384592 |
apr_bucket_brigade *brigade = NULL;
|
|
Packit Service |
384592 |
apr_bucket *bucket = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Set the status line explicitly for the error document */
|
|
Packit Service |
384592 |
f->r->status_line = ap_get_status_line(status);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
brigade = apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc);
|
|
Packit Service |
384592 |
if (brigade == NULL) return APR_EGENERAL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
bucket = ap_bucket_error_create(status, NULL, f->r->pool, f->r->connection->bucket_alloc);
|
|
Packit Service |
384592 |
if (bucket == NULL) return APR_EGENERAL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
bucket = apr_bucket_eos_create(f->r->connection->bucket_alloc);
|
|
Packit Service |
384592 |
if (bucket == NULL) return APR_EGENERAL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
APR_BRIGADE_INSERT_TAIL(brigade, bucket);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
ap_pass_brigade(f->next, brigade);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* NOTE:
|
|
Packit Service |
384592 |
* It may not matter what we do from the filter as it may be too
|
|
Packit Service |
384592 |
* late to even generate an error (already sent to client). Nick Kew
|
|
Packit Service |
384592 |
* recommends to return APR_EGENERAL in hopes that the handler in control
|
|
Packit Service |
384592 |
* will notice and do The Right Thing. So, that is what we do now.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return APR_EGENERAL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Execute system command. First line of the output will be returned in
|
|
Packit Service |
384592 |
* the "output" parameter.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
int apache2_exec(modsec_rec *msr, const char *command, const char **argv, char **output) {
|
|
Packit Service |
384592 |
apr_procattr_t *procattr = NULL;
|
|
Packit Service |
384592 |
apr_proc_t *procnew = NULL;
|
|
Packit Service |
384592 |
apr_status_t rc = APR_SUCCESS;
|
|
Packit Service |
384592 |
const char *const *env = NULL;
|
|
Packit Service |
384592 |
apr_file_t *script_out = NULL;
|
|
Packit Service |
384592 |
request_rec *r = msr->r;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (argv == NULL) {
|
|
Packit Service |
384592 |
argv = apr_pcalloc(r->pool, 3 * sizeof(char *));
|
|
Packit Service |
384592 |
argv[0] = command;
|
|
Packit Service |
384592 |
argv[1] = NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
ap_add_cgi_vars(r);
|
|
Packit Service |
384592 |
ap_add_common_vars(r);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* PHP hack, getting around its silly security checks. */
|
|
Packit Service |
384592 |
apr_table_add(r->subprocess_env, "PATH_TRANSLATED", command);
|
|
Packit Service |
384592 |
apr_table_add(r->subprocess_env, "REDIRECT_STATUS", "302");
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
env = (const char * const *)ap_create_environment(r->pool, r->subprocess_env);
|
|
Packit Service |
384592 |
if (env == NULL) {
|
|
Packit Service |
384592 |
msr_log(msr, 1, "Exec: Unable to create environment.");
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
procnew = apr_pcalloc(r->pool, sizeof(*procnew));
|
|
Packit Service |
384592 |
if (procnew == NULL) {
|
|
Packit Service |
384592 |
msr_log(msr, 1, "Exec: Unable to allocate %lu bytes.", (unsigned long)sizeof(*procnew));
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_procattr_create(&procattr, r->pool);
|
|
Packit Service |
384592 |
if (procattr == NULL) {
|
|
Packit Service |
384592 |
msr_log(msr, 1, "Exec: Unable to create procattr.");
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_procattr_io_set(procattr, APR_NO_PIPE, APR_FULL_BLOCK, APR_NO_PIPE);
|
|
Packit Service |
384592 |
apr_procattr_cmdtype_set(procattr, APR_SHELLCMD);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (msr->txcfg->debuglog_level >= 9) {
|
|
Packit Service |
384592 |
msr_log(msr, 9, "Exec: %s", log_escape_nq(r->pool, command));
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc = apr_proc_create(procnew, command, argv, env, procattr, r->pool);
|
|
Packit Service |
384592 |
if (rc != APR_SUCCESS) {
|
|
Packit Service |
384592 |
msr_log(msr, 1, "Exec: Execution failed: %s (%s)", log_escape_nq(r->pool, command),
|
|
Packit Service |
384592 |
get_apr_error(r->pool, rc));
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_pool_note_subprocess(r->pool, procnew, APR_KILL_AFTER_TIMEOUT);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
script_out = procnew->out;
|
|
Packit Service |
384592 |
if (!script_out) {
|
|
Packit Service |
384592 |
msr_log(msr, 1, "Exec: Failed to get script output pipe.");
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_file_pipe_timeout_set(script_out, r->server->timeout);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Now read from the pipe. */
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
char buf[260] = "";
|
|
Packit Service |
384592 |
char *p = buf;
|
|
Packit Service |
384592 |
apr_size_t nbytes = 255;
|
|
Packit Service |
384592 |
apr_status_t rc2;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
rc2 = apr_file_read(script_out, buf, &nbytes);
|
|
Packit Service |
384592 |
if (rc2 == APR_SUCCESS) {
|
|
Packit Service |
384592 |
buf[nbytes] = 0;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* if there is more than one line ignore them */
|
|
Packit Service |
384592 |
while(*p != 0) {
|
|
Packit Service |
384592 |
if (*p == 0x0a) *p = 0;
|
|
Packit Service |
384592 |
p++;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (msr->txcfg->debuglog_level >= 4) {
|
|
Packit Service |
384592 |
msr_log(msr, 4, "Exec: First line from script output: \"%s\"",
|
|
Packit Service |
384592 |
log_escape(r->pool, buf));
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (output != NULL) *output = apr_pstrdup(r->pool, buf);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Soak up the remaining data. */
|
|
Packit Service |
384592 |
nbytes = 255;
|
|
Packit Service |
384592 |
while(apr_file_read(script_out, buf, &nbytes) == APR_SUCCESS) nbytes = 255;
|
|
Packit Service |
384592 |
} else {
|
|
Packit Service |
384592 |
msr_log(msr, 1, "Exec: Execution failed while reading output: %s (%s)",
|
|
Packit Service |
384592 |
log_escape_nq(r->pool, command),
|
|
Packit Service |
384592 |
get_apr_error(r->pool, rc2));
|
|
Packit Service |
384592 |
return -1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
apr_proc_wait(procnew, NULL, NULL, APR_WAIT);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return 1;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Returns a new string that contains the error
|
|
Packit Service |
384592 |
* message for the given return code.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
char *get_apr_error(apr_pool_t *p, apr_status_t rc) {
|
|
Packit Service |
384592 |
char *text = apr_pcalloc(p, 201);
|
|
Packit Service |
384592 |
if (text == NULL) return NULL;
|
|
Packit Service |
384592 |
apr_strerror(rc, text, 200);
|
|
Packit Service |
384592 |
return text;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Retrieve named environment variable.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
char *get_env_var(request_rec *r, char *name) {
|
|
Packit Service |
384592 |
char *result = (char *)apr_table_get(r->notes, name);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (result == NULL) {
|
|
Packit Service |
384592 |
result = (char *)apr_table_get(r->subprocess_env, name);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (result == NULL) {
|
|
Packit Service |
384592 |
result = getenv(name);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return result;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Extended internal log helper function. Use msr_log instead. If fixup is
|
|
Packit Service |
384592 |
* true, the message will be stripped of any trailing newline and any
|
|
Packit Service |
384592 |
* required bytes will be escaped.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *msr,
|
|
Packit Service |
384592 |
int level, int fixup, const char *text, va_list ap)
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
apr_size_t nbytes, nbytes_written;
|
|
Packit Service |
384592 |
apr_file_t *debuglog_fd = NULL;
|
|
Packit Service |
384592 |
int filter_debug_level = 0;
|
|
Packit Service |
384592 |
char *remote = NULL;
|
|
Packit Service |
384592 |
char *parse_remote = NULL;
|
|
Packit Service |
384592 |
char *saved = NULL;
|
|
Packit Service |
384592 |
char *str = NULL;
|
|
Packit Service |
384592 |
char str1[1024] = "";
|
|
Packit Service |
384592 |
char str2[1256] = "";
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Find the logging FD and determine the logging level from configuration. */
|
|
Packit Service |
384592 |
if (dcfg != NULL) {
|
|
Packit Service |
384592 |
if ((dcfg->debuglog_fd != NULL)&&(dcfg->debuglog_fd != NOT_SET_P)) {
|
|
Packit Service |
384592 |
debuglog_fd = dcfg->debuglog_fd;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (dcfg->debuglog_level != NOT_SET) {
|
|
Packit Service |
384592 |
filter_debug_level = dcfg->debuglog_level;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Return immediately if we don't have where to write
|
|
Packit Service |
384592 |
* or if the log level of the message is higher than
|
|
Packit Service |
384592 |
* wanted in the log.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
if ((level > 3)&&( (debuglog_fd == NULL) || (level > filter_debug_level) )) return;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Construct the message. */
|
|
Packit Service |
384592 |
apr_vsnprintf(str1, sizeof(str1), text, ap);
|
|
Packit Service |
384592 |
if (fixup) {
|
|
Packit Service |
384592 |
int len = strlen(str1);
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Strip line ending. */
|
|
Packit Service |
384592 |
if (len && str1[len - 1] == '\n') {
|
|
Packit Service |
384592 |
str1[len - 1] = '\0';
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
if (len > 1 && str1[len - 2] == '\r') {
|
|
Packit Service |
384592 |
str1[len - 2] = '\0';
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Construct the log entry. */
|
|
Packit Service |
384592 |
apr_snprintf(str2, sizeof(str2),
|
|
Packit Service |
384592 |
"[%s] [%s/sid#%pp][rid#%pp][%s][%d] %s\n",
|
|
Packit Service |
384592 |
current_logtime(msr->mp), ap_get_server_name(r), (r->server),
|
|
Packit Service |
384592 |
r, ((r->uri == NULL) ? "" : log_escape_nq(msr->mp, r->uri)),
|
|
Packit Service |
384592 |
level, (fixup ? log_escape_nq(msr->mp, str1) : str1));
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Write to the debug log. */
|
|
Packit Service |
384592 |
if ((debuglog_fd != NULL)&&(level <= filter_debug_level)) {
|
|
Packit Service |
384592 |
nbytes = strlen(str2);
|
|
Packit Service |
384592 |
apr_file_write_full(debuglog_fd, str2, nbytes, &nbytes_written);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Send message levels 1-3 to the Apache error log and
|
|
Packit Service |
384592 |
* add it to the message list in the audit log. */
|
|
Packit Service |
384592 |
if (level <= 3) {
|
|
Packit Service |
384592 |
char *unique_id = (char *)get_env_var(r, "UNIQUE_ID");
|
|
Packit Service |
384592 |
char *hostname = (char *)msr->hostname;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (unique_id != NULL) {
|
|
Packit Service |
384592 |
unique_id = apr_psprintf(msr->mp, " [unique_id \"%s\"]",
|
|
Packit Service |
384592 |
log_escape(msr->mp, unique_id));
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else unique_id = "";
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (hostname != NULL) {
|
|
Packit Service |
384592 |
hostname = apr_psprintf(msr->mp, " [hostname \"%s\"]",
|
|
Packit Service |
384592 |
log_escape(msr->mp, hostname));
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
else hostname = "";
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
|
|
Packit Service |
384592 |
ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
|
|
Packit Service |
384592 |
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", r->useragent_ip ? r->useragent_ip : r->connection->client_ip, str1,
|
|
Packit Service |
384592 |
hostname, log_escape(msr->mp, r->uri), unique_id);
|
|
Packit Service |
384592 |
#else
|
|
Packit Service |
384592 |
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
|
|
Packit Service |
384592 |
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", msr->remote_addr ? msr->remote_addr : r->connection->remote_ip, str1,
|
|
Packit Service |
384592 |
hostname, log_escape(msr->mp, r->uri), unique_id);
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/* Add this message to the list. */
|
|
Packit Service |
384592 |
if (msr != NULL) {
|
|
Packit Service |
384592 |
/* Force relevency if this is an alert */
|
|
Packit Service |
384592 |
msr->is_relevant++;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
*(const char **)apr_array_push(msr->alerts) = apr_pstrdup(msr->mp, str1);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Logs one message at the given level to the debug log (and to the
|
|
Packit Service |
384592 |
* Apache error log if the message is important enough.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
void msr_log(modsec_rec *msr, int level, const char *text, ...) {
|
|
Packit Service |
384592 |
va_list ap;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
va_start(ap, text);
|
|
Packit Service |
384592 |
internal_log_ex(msr->r, msr->txcfg, msr, level, 0, text, ap);
|
|
Packit Service |
384592 |
va_end(ap);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Logs one message at level 3 to the debug log and to the
|
|
Packit Service |
384592 |
* Apache error log. This is intended for error callbacks.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
void msr_log_error(modsec_rec *msr, const char *text, ...) {
|
|
Packit Service |
384592 |
va_list ap;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
va_start(ap, text);
|
|
Packit Service |
384592 |
internal_log_ex(msr->r, msr->txcfg, msr, 3, 1, text, ap);
|
|
Packit Service |
384592 |
va_end(ap);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Logs one message at level 4 to the debug log and to the
|
|
Packit Service |
384592 |
* Apache error log. This is intended for warning callbacks.
|
|
Packit Service |
384592 |
*
|
|
Packit Service |
384592 |
* The 'text' will first be escaped.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
void msr_log_warn(modsec_rec *msr, const char *text, ...) {
|
|
Packit Service |
384592 |
va_list ap;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
va_start(ap, text);
|
|
Packit Service |
384592 |
internal_log_ex(msr->r, msr->txcfg, msr, 4, 1, text, ap);
|
|
Packit Service |
384592 |
va_end(ap);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Converts an Apache error log message into one line of text.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
char *format_error_log_message(apr_pool_t *mp, error_message_t *em) {
|
|
Packit Service |
384592 |
char *s_file = "", *s_line = "", *s_level = "";
|
|
Packit Service |
384592 |
char *s_status = "", *s_message = "";
|
|
Packit Service |
384592 |
char *msg = NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (em == NULL) return NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
#ifndef LOG_NO_FILENAME
|
|
Packit Service |
384592 |
if (em->file != NULL) {
|
|
Packit Service |
384592 |
s_file = apr_psprintf(mp, "[file \"%s\"] ",
|
|
Packit Service |
384592 |
log_escape(mp, (char *)em->file));
|
|
Packit Service |
384592 |
if (s_file == NULL) return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (em->line > 0) {
|
|
Packit Service |
384592 |
s_line = apr_psprintf(mp, "[line %d] ", em->line);
|
|
Packit Service |
384592 |
if (s_line == NULL) return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
#endif
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
s_level = apr_psprintf(mp, "[level %d] ", em->level);
|
|
Packit Service |
384592 |
if (s_level == NULL) return NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (em->status != 0) {
|
|
Packit Service |
384592 |
s_status = apr_psprintf(mp, "[status %d] ", em->status);
|
|
Packit Service |
384592 |
if (s_status == NULL) return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (em->message != NULL) {
|
|
Packit Service |
384592 |
s_message = log_escape_nq(mp, em->message);
|
|
Packit Service |
384592 |
if (s_message == NULL) return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
msg = apr_psprintf(mp, "%s%s%s%s%s", s_file, s_line, s_level, s_status, s_message);
|
|
Packit Service |
384592 |
if (msg == NULL) return NULL;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return msg;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
/**
|
|
Packit Service |
384592 |
* Determines the reponse protocol Apache will use (or has used)
|
|
Packit Service |
384592 |
* to respond to the given request.
|
|
Packit Service |
384592 |
*/
|
|
Packit Service |
384592 |
const char *get_response_protocol(request_rec *r) {
|
|
Packit Service |
384592 |
int proto_num = r->proto_num;
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (r->assbackwards) {
|
|
Packit Service |
384592 |
return NULL;
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (proto_num > HTTP_VERSION(1,0)
|
|
Packit Service |
384592 |
&& apr_table_get(r->subprocess_env, "downgrade-1.0"))
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
proto_num = HTTP_VERSION(1,0);
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
if (proto_num == HTTP_VERSION(1,0)
|
|
Packit Service |
384592 |
&& apr_table_get(r->subprocess_env, "force-response-1.0"))
|
|
Packit Service |
384592 |
{
|
|
Packit Service |
384592 |
return "HTTP/1.0";
|
|
Packit Service |
384592 |
}
|
|
Packit Service |
384592 |
|
|
Packit Service |
384592 |
return AP_SERVER_PROTOCOL;
|
|
Packit Service |
384592 |
}
|