diff options
Diffstat (limited to 'modules/metadata')
-rw-r--r-- | modules/metadata/mod_cern_meta.c | 4 | ||||
-rw-r--r-- | modules/metadata/mod_headers.c | 30 | ||||
-rw-r--r-- | modules/metadata/mod_mime_magic.c | 26 | ||||
-rw-r--r-- | modules/metadata/mod_remoteip.c | 38 | ||||
-rw-r--r-- | modules/metadata/mod_unique_id.c | 54 | ||||
-rw-r--r-- | modules/metadata/mod_usertrack.c | 67 |
6 files changed, 146 insertions, 73 deletions
diff --git a/modules/metadata/mod_cern_meta.c b/modules/metadata/mod_cern_meta.c index 09a41e1..3f36b2d 100644 --- a/modules/metadata/mod_cern_meta.c +++ b/modules/metadata/mod_cern_meta.c @@ -240,7 +240,7 @@ static int scan_meta_file(request_rec *r, apr_file_t *f) while (apr_isspace(*l)) ++l; - if (!strcasecmp(w, "Content-type")) { + if (!ap_cstr_casecmp(w, "Content-type")) { char *tmp; /* Nuke trailing whitespace */ @@ -252,7 +252,7 @@ static int scan_meta_file(request_rec *r, apr_file_t *f) ap_content_type_tolower(tmp); ap_set_content_type(r, tmp); } - else if (!strcasecmp(w, "Status")) { + else if (!ap_cstr_casecmp(w, "Status")) { sscanf(l, "%d", &r->status); r->status_line = apr_pstrdup(r->pool, l); } diff --git a/modules/metadata/mod_headers.c b/modules/metadata/mod_headers.c index 1ea970d..ef812cd 100644 --- a/modules/metadata/mod_headers.c +++ b/modules/metadata/mod_headers.c @@ -78,13 +78,12 @@ #include "httpd.h" #include "http_config.h" #include "http_request.h" +#include "http_ssl.h" #include "http_log.h" #include "util_filter.h" #include "http_protocol.h" #include "ap_expr.h" -#include "mod_ssl.h" /* for the ssl_var_lookup optional function defn */ - /* format_tag_hash is initialized during pre-config */ static apr_hash_t *format_tag_hash; @@ -161,9 +160,6 @@ typedef struct { module AP_MODULE_DECLARE_DATA headers_module; -/* Pointer to ssl_var_lookup, if available. */ -static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *header_ssl_lookup = NULL; - /* * Tag formatting functions */ @@ -210,17 +206,12 @@ static const char *header_request_env_var(request_rec *r, char *a) static const char *header_request_ssl_var(request_rec *r, char *name) { - if (header_ssl_lookup) { - const char *val = header_ssl_lookup(r->pool, r->server, - r->connection, r, name); - if (val && val[0]) - return unwrap_header(r->pool, val); - else - return "(null)"; - } - else { + const char *val = ap_ssl_var_lookup(r->pool, r->server, + r->connection, r, name); + if (val && val[0]) + return unwrap_header(r->pool, val); + else return "(null)"; - } } static const char *header_request_loadavg(request_rec *r, char *a) @@ -668,7 +659,7 @@ static const char *process_regexp(header_entry *hdr, const char *value, static int echo_header(void *v, const char *key, const char *val) { - edit_do *ed = v; + echo_do *ed = (echo_do *)v; /* If the input header (key) matches the regex, echo it intact to * r->headers_out. @@ -791,14 +782,14 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers, } break; case hdr_set: - if (!strcasecmp(hdr->header, "Content-Type")) { + if (!ap_cstr_casecmp(hdr->header, "Content-Type")) { ap_set_content_type(r, process_tags(hdr, r)); } apr_table_setn(headers, hdr->header, process_tags(hdr, r)); break; case hdr_setifempty: if (NULL == apr_table_get(headers, hdr->header)) { - if (!strcasecmp(hdr->header, "Content-Type")) { + if (!ap_cstr_casecmp(hdr->header, "Content-Type")) { ap_set_content_type(r, process_tags(hdr, r)); } apr_table_setn(headers, hdr->header, process_tags(hdr, r)); @@ -814,7 +805,7 @@ static int do_headers_fixup(request_rec *r, apr_table_t *headers, break; case hdr_edit: case hdr_edit_r: - if (!strcasecmp(hdr->header, "Content-Type") && r->content_type) { + if (!ap_cstr_casecmp(hdr->header, "Content-Type") && r->content_type) { const char *repl = process_regexp(hdr, r->content_type, r); if (repl == NULL) return 0; @@ -989,7 +980,6 @@ static int header_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp) static int header_post_config(apr_pool_t *pconf, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { - header_ssl_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); return OK; } diff --git a/modules/metadata/mod_mime_magic.c b/modules/metadata/mod_mime_magic.c index 22dadaf..7dac4fd 100644 --- a/modules/metadata/mod_mime_magic.c +++ b/modules/metadata/mod_mime_magic.c @@ -257,7 +257,7 @@ static int fsmagic(request_rec *r, const char *fn); #define L_MAIL 8 /* Electronic mail */ #define L_NEWS 9 /* Usenet Netnews */ -static const char *types[] = +static const char *const types[] = { "text/html", /* HTML */ "text/plain", /* "c program text", */ @@ -462,7 +462,6 @@ typedef struct { typedef struct { magic_rsl *head; /* result string list */ magic_rsl *tail; - unsigned suf_recursion; /* recursion depth in suffix check */ } magic_req_rec; /* @@ -606,7 +605,7 @@ static int magic_rsl_putchar(request_rec *r, char c) /* high overhead for 1 char - just hope they don't do this much */ str[0] = c; str[1] = '\0'; - return magic_rsl_add(r, str); + return magic_rsl_add(r, apr_pstrdup(r->pool, str)); } /* allocate and copy a contiguous string from a result string list */ @@ -984,7 +983,7 @@ static int apprentice(server_rec *s, apr_pool_t *p) #if MIME_MAGIC_DEBUG ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01516) - MODNAME ": apprentice conf=%x file=%s m=%s m->next=%s last=%s", + MODNAME ": apprentice conf=%pp file=%s m=%s m->next=%s last=%s", conf, conf->magicfile ? conf->magicfile : "NULL", conf->magic ? "set" : "NULL", @@ -1276,7 +1275,7 @@ static int parse(server_rec *serv, apr_pool_t *p, char *l, int lineno) #if MIME_MAGIC_DEBUG ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, serv, APLOGNO(01525) - MODNAME ": parse line=%d m=%x next=%x cont=%d desc=%s", + MODNAME ": parse line=%d m=%pp next=%pp cont=%d desc=%s", lineno, m, m->next, m->cont_level, m->desc); #endif /* MIME_MAGIC_DEBUG */ @@ -1541,7 +1540,7 @@ static int match(request_rec *r, unsigned char *s, apr_size_t nbytes) #if MIME_MAGIC_DEBUG ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01529) - MODNAME ": match conf=%x file=%s m=%s m->next=%s last=%s", + MODNAME ": match conf=%pp file=%s m=%s m->next=%s last=%s", conf, conf->magicfile ? conf->magicfile : "NULL", conf->magic ? "set" : "NULL", @@ -1591,7 +1590,7 @@ static int match(request_rec *r, unsigned char *s, apr_size_t nbytes) #if MIME_MAGIC_DEBUG rule_counter++; ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01532) - MODNAME ": line=%d mc=%x mc->next=%x cont=%d desc=%s", + MODNAME ": line=%d mc=%pp mc->next=%pp cont=%d desc=%s", m_cont->lineno, m_cont, m_cont->next, m_cont->cont_level, m_cont->desc); @@ -2044,12 +2043,12 @@ static int ascmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes) * - uncompress old into new, using method, return sizeof new */ -static struct { - char *magic; +static const struct { + const char *magic; apr_size_t maglen; - char *argv[3]; + const char *argv[3]; int silent; - char *encoding; /* MUST be lowercase */ + const char *encoding; /* MUST be lowercase */ } compr[] = { /* we use gzip here rather than uncompress because we have to pass @@ -2077,7 +2076,7 @@ static struct { }, }; -static int ncompr = sizeof(compr) / sizeof(compr[0]); +#define ncompr (sizeof(compr) / sizeof(compr[0])) static int zmagic(request_rec *r, unsigned char *buf, apr_size_t nbytes) { @@ -2177,11 +2176,12 @@ static int uncompress(request_rec *r, int method, parm.method = method; /* We make a sub_pool so that we can collect our child early, otherwise - * there are cases (i.e. generating directory indicies with mod_autoindex) + * there are cases (i.e. generating directory indices with mod_autoindex) * where we would end up with LOTS of zombies. */ if (apr_pool_create(&sub_context, r->pool) != APR_SUCCESS) return -1; + apr_pool_tag(sub_context, "magic_uncompress"); if ((rv = create_uncompress_child(&parm, sub_context, &pipe_out)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01553) diff --git a/modules/metadata/mod_remoteip.c b/modules/metadata/mod_remoteip.c index 4572ce1..045e988 100644 --- a/modules/metadata/mod_remoteip.c +++ b/modules/metadata/mod_remoteip.c @@ -393,7 +393,7 @@ static void remoteip_warn_enable_conflict(remoteip_addr_info *prev, server_rec * ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, new, APLOGNO(03491) "RemoteIPProxyProtocol: previous setting for %s:%hu from virtual " - "host {%s:%hu in %s} is being overriden by virtual host " + "host {%s:%hu in %s} is being overridden by virtual host " "{%s:%hu in %s}; new setting is '%s'", buf, prev->addr->port, prev->source->server_hostname, prev->source->addrs->host_port, prev->source->defn_name, @@ -987,15 +987,13 @@ static remoteip_parse_status_t remoteip_process_v2_header(conn_rec *c, return HDR_ERROR; #endif default: - /* unsupported protocol, keep local connection address */ - return HDR_DONE; + /* unsupported protocol */ + ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(10183) + "RemoteIPProxyProtocol: unsupported protocol %.2hx", + (unsigned short)hdr->v2.fam); + return HDR_ERROR; } break; /* we got a sockaddr now */ - - case 0x00: /* LOCAL command */ - /* keep local connection address for LOCAL */ - return HDR_DONE; - default: /* not a supported command */ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(03507) @@ -1087,11 +1085,24 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f, /* try to read a header's worth of data */ while (!ctx->done) { if (APR_BRIGADE_EMPTY(ctx->bb)) { - ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block, - ctx->need - ctx->rcvd); + apr_off_t got, want = ctx->need - ctx->rcvd; + + ret = ap_get_brigade(f->next, ctx->bb, ctx->mode, block, want); if (ret != APR_SUCCESS) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10184) + "failed reading input"); return ret; } + + ret = apr_brigade_length(ctx->bb, 1, &got); + if (ret || got > want) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, ret, f->c, APLOGNO(10185) + "RemoteIPProxyProtocol header too long, " + "got %" APR_OFF_T_FMT " expected %" APR_OFF_T_FMT, + got, want); + f->c->aborted = 1; + return APR_ECONNABORTED; + } } if (APR_BRIGADE_EMPTY(ctx->bb)) { return block == APR_NONBLOCK_READ ? APR_SUCCESS : APR_EOF; @@ -1139,6 +1150,13 @@ static apr_status_t remoteip_input_filter(ap_filter_t *f, if (ctx->rcvd >= MIN_V2_HDR_LEN) { ctx->need = MIN_V2_HDR_LEN + remoteip_get_v2_len((proxy_header *) ctx->header); + if (ctx->need > sizeof(proxy_v2)) { + ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(10186) + "RemoteIPProxyProtocol protocol header length too long"); + f->c->aborted = 1; + apr_brigade_destroy(ctx->bb); + return APR_ECONNABORTED; + } } if (ctx->rcvd >= ctx->need) { psts = remoteip_process_v2_header(f->c, conn_conf, diff --git a/modules/metadata/mod_unique_id.c b/modules/metadata/mod_unique_id.c index 0b05fbf..2555749 100644 --- a/modules/metadata/mod_unique_id.c +++ b/modules/metadata/mod_unique_id.c @@ -26,6 +26,11 @@ #include "apr_general.h" /* for APR_OFFSETOF */ #include "apr_network_io.h" +#ifdef APR_HAS_THREADS +#include "apr_atomic.h" /* for apr_atomic_inc32 */ +#include "mpm_common.h" /* for ap_mpm_query */ +#endif + #include "httpd.h" #include "http_config.h" #include "http_log.h" @@ -104,7 +109,7 @@ typedef struct { /* * Sun Jun 7 05:43:49 CEST 1998 -- Alvaro * More comments: - * 1) The UUencoding prodecure is now done in a general way, avoiding the problems + * 1) The UUencoding procedure is now done in a general way, avoiding the problems * with sizes and paddings that can arise depending on the architecture. Now the * offsets and sizes of the elements of the unique_id_rec structure are calculated * in unique_id_global_init; and then used to duplicate the structure without the @@ -123,6 +128,10 @@ typedef struct { * XXX: thrashing. */ static unique_id_rec cur_unique_id; +static apr_uint32_t cur_unique_counter; +#ifdef APR_HAS_THREADS +static int is_threaded_mpm; +#endif /* * Number of elements in the structure unique_id_rec. @@ -160,6 +169,11 @@ static int unique_id_global_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *pt static void unique_id_child_init(apr_pool_t *p, server_rec *s) { +#ifdef APR_HAS_THREADS + is_threaded_mpm = 0; + ap_mpm_query(AP_MPMQ_IS_THREADED, &is_threaded_mpm); +#endif + ap_random_insecure_bytes(&cur_unique_id.root, sizeof(cur_unique_id.root)); @@ -168,28 +182,29 @@ static void unique_id_child_init(apr_pool_t *p, server_rec *s) * against restart problems, and a little less protection against a clock * going backwards in time. */ - ap_random_insecure_bytes(&cur_unique_id.counter, - sizeof(cur_unique_id.counter)); + ap_random_insecure_bytes(&cur_unique_counter, + sizeof(cur_unique_counter)); } -/* NOTE: This is *NOT* the same encoding used by base64encode ... the last two - * characters should be + and /. But those two characters have very special - * meanings in URLs, and we want to make it easy to use identifiers in - * URLs. So we replace them with @ and -. - */ +/* Use the base64url encoding per RFC 4648, avoiding characters which + * are not safe in URLs. ### TODO: can switch to apr_encode_*. */ static const char uuencoder[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '@', '-', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_', }; +#ifndef APR_UINT16_MAX +#define APR_UINT16_MAX 0xffffu +#endif + static const char *gen_unique_id(const request_rec *r) { char *str; /* - * Buffer padded with two final bytes, used to copy the unique_id_red + * Buffer padded with two final bytes, used to copy the unique_id_rec * structure without the internal paddings that it could have. */ unique_id_rec new_unique_id; @@ -197,14 +212,24 @@ static const char *gen_unique_id(const request_rec *r) unique_id_rec foo; unsigned char pad[2]; } paddedbuf; + apr_uint32_t counter; unsigned char *x,*y; - unsigned short counter; int i,j,k; memcpy(&new_unique_id.root, &cur_unique_id.root, ROOT_SIZE); - new_unique_id.counter = cur_unique_id.counter; new_unique_id.stamp = htonl((unsigned int)apr_time_sec(r->request_time)); new_unique_id.thread_index = htonl((unsigned int)r->connection->id); +#ifdef APR_HAS_THREADS + if (is_threaded_mpm) + counter = apr_atomic_inc32(&cur_unique_counter); + else +#endif + counter = cur_unique_counter++; + + /* The counter is two bytes for the uuencoded unique id, in network + * byte order. + */ + new_unique_id.counter = htons(counter % APR_UINT16_MAX); /* we'll use a temporal buffer to avoid uuencoding the possible internal * paddings of the original structure */ @@ -236,11 +261,6 @@ static const char *gen_unique_id(const request_rec *r) } str[k++] = '\0'; - /* and increment the identifier for the next call */ - - counter = ntohs(new_unique_id.counter) + 1; - cur_unique_id.counter = htons(counter); - return str; } diff --git a/modules/metadata/mod_usertrack.c b/modules/metadata/mod_usertrack.c index 73a9f45..55252ec 100644 --- a/modules/metadata/mod_usertrack.c +++ b/modules/metadata/mod_usertrack.c @@ -86,6 +86,9 @@ typedef struct { const char *cookie_domain; char *regexp_string; /* used to compile regexp; save for debugging */ ap_regex_t *regexp; /* used to find usertrack cookie in cookie header */ + int is_secure; + int is_httponly; + const char *samesite; } cookie_dir_rec; /* Make Cookie: Now we have to generate something that is going to be @@ -143,6 +146,21 @@ static void make_cookie(request_rec *r) : ""), NULL); } + if (dcfg->samesite != NULL) { + new_cookie = apr_pstrcat(r->pool, new_cookie, "; ", + dcfg->samesite, + NULL); + } + if (dcfg->is_secure) { + new_cookie = apr_pstrcat(r->pool, new_cookie, "; Secure", + NULL); + } + if (dcfg->is_httponly) { + new_cookie = apr_pstrcat(r->pool, new_cookie, "; HttpOnly", + NULL); + } + + apr_table_addn(r->err_headers_out, (dcfg->style == CT_COOKIE2 ? "Set-Cookie2" : "Set-Cookie"), @@ -266,9 +284,9 @@ static void *make_cookie_dir(apr_pool_t *p, char *d) dcfg = (cookie_dir_rec *) apr_pcalloc(p, sizeof(cookie_dir_rec)); dcfg->cookie_name = COOKIE_NAME; - dcfg->cookie_domain = NULL; dcfg->style = CT_UNSET; - dcfg->enabled = 0; + /* calloc'ed to disabled: enabled, cookie_domain, samesite, is_secure, + * is_httponly */ /* In case the user does not use the CookieName directive, * we need to compile the regexp for the default cookie name. */ @@ -277,14 +295,6 @@ static void *make_cookie_dir(apr_pool_t *p, char *d) return dcfg; } -static const char *set_cookie_enable(cmd_parms *cmd, void *mconfig, int arg) -{ - cookie_dir_rec *dcfg = mconfig; - - dcfg->enabled = arg; - return NULL; -} - static const char *set_cookie_exp(cmd_parms *parms, void *dummy, const char *arg) { @@ -429,6 +439,31 @@ static const char *set_cookie_style(cmd_parms *cmd, void *mconfig, return NULL; } +/* + * SameSite enabled disabled + */ + +static const char *set_samesite_value(cmd_parms *cmd, void *mconfig, + const char *name) +{ + cookie_dir_rec *dcfg; + + dcfg = (cookie_dir_rec *) mconfig; + + if (strcasecmp(name, "strict") == 0) { + dcfg->samesite = "SameSite=Strict"; + } else if (strcasecmp(name, "lax") == 0) { + dcfg->samesite = "SameSite=Lax"; + } else if (strcasecmp(name, "none") == 0) { + dcfg->samesite = "SameSite=None"; + } else { + return "CookieSameSite accepts 'Strict', 'Lax', or 'None'"; + } + + + return NULL; +} + static const command_rec cookie_log_cmds[] = { AP_INIT_TAKE1("CookieExpires", set_cookie_exp, NULL, OR_FILEINFO, "an expiry date code"), @@ -436,10 +471,20 @@ static const command_rec cookie_log_cmds[] = { "domain to which this cookie applies"), AP_INIT_TAKE1("CookieStyle", set_cookie_style, NULL, OR_FILEINFO, "'Netscape', 'Cookie' (RFC2109), or 'Cookie2' (RFC2965)"), - AP_INIT_FLAG("CookieTracking", set_cookie_enable, NULL, OR_FILEINFO, + AP_INIT_FLAG("CookieTracking", ap_set_flag_slot, + (void *)APR_OFFSETOF(cookie_dir_rec, enabled), OR_FILEINFO, "whether or not to enable cookies"), AP_INIT_TAKE1("CookieName", set_cookie_name, NULL, OR_FILEINFO, "name of the tracking cookie"), + AP_INIT_TAKE1("CookieSameSite", set_samesite_value, NULL, OR_FILEINFO, + "SameSite setting"), + AP_INIT_FLAG("CookieSecure", ap_set_flag_slot, + (void *)APR_OFFSETOF(cookie_dir_rec, is_secure), OR_FILEINFO, + "is cookie secure"), + AP_INIT_FLAG("CookieHttpOnly", ap_set_flag_slot, + (void *)APR_OFFSETOF(cookie_dir_rec, is_httponly),OR_FILEINFO, + "is cookie http only"), + {NULL} }; |