diff --git a/CHANGES b/CHANGES index eb887ad3f0..d7248aff27 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,10 @@ Changes with Apache 2.3.3 + *) ServerTokens now accepts 'Off' which disables sending of + Server: header and sets SERVER_SOFTWARE to empty. + [Jim Jagielski] + *) mod_headers: generalise the envclause to support expression evaluation with ap_expr parser [Nick Kew] diff --git a/docs/manual/mod/core.xml b/docs/manual/mod/core.xml index e5ac16265c..089a7b97f1 100644 --- a/docs/manual/mod/core.xml +++ b/docs/manual/mod/core.xml @@ -2873,6 +2873,11 @@ header information about compiled-in modules.

+
ServerTokens Off
+ +
Server sends no Server: header + (and SERVER_SOFTWARE is blank)
+
ServerTokens Prod[uctOnly]
Server sends (e.g.): Server: diff --git a/modules/http/http_filters.c b/modules/http/http_filters.c index d6529754ae..7fb5e18f17 100644 --- a/modules/http/http_filters.c +++ b/modules/http/http_filters.c @@ -874,6 +874,7 @@ static void basic_http_header(request_rec *r, apr_bucket_brigade *bb, { char *date; const char *server; + const char *us = ap_get_server_banner(); header_struct h; struct iovec vec[4]; @@ -930,19 +931,25 @@ static void basic_http_header(request_rec *r, apr_bucket_brigade *bb, if (server) { form_header_field(&h, "Server", server); } else { - form_header_field(&h, "Server", ap_get_server_banner()); + if (*us) { + form_header_field(&h, "Server", ap_get_server_banner()); + } } } else { date = apr_palloc(r->pool, APR_RFC822_DATE_LEN); ap_recent_rfc822_date(date, r->request_time); form_header_field(&h, "Date", date); - form_header_field(&h, "Server", ap_get_server_banner()); + if (*us) { + form_header_field(&h, "Server", ap_get_server_banner()); + } } /* unset so we don't send them again */ apr_table_unset(r->headers_out, "Date"); /* Avoid bogosity */ - apr_table_unset(r->headers_out, "Server"); + if (*us) { + apr_table_unset(r->headers_out, "Server"); + } } AP_DECLARE(void) ap_basic_http_header(request_rec *r, apr_bucket_brigade *bb) diff --git a/modules/proxy/mod_proxy_connect.c b/modules/proxy/mod_proxy_connect.c index c7225c51b6..5b72eadd91 100644 --- a/modules/proxy/mod_proxy_connect.c +++ b/modules/proxy/mod_proxy_connect.c @@ -229,7 +229,7 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker, "CONNECT %s HTTP/1.0" CRLF, r->uri); apr_socket_send(sock, buffer, &nbytes); nbytes = apr_snprintf(buffer, sizeof(buffer), - "Proxy-agent: %s" CRLF CRLF, ap_get_server_banner()); + "Proxy-agent: %s" CRLF CRLF, ap_get_server_description()); apr_socket_send(sock, buffer, &nbytes); } else { diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c index 136f91269e..582cdc9ecf 100644 --- a/modules/proxy/mod_proxy_ftp.c +++ b/modules/proxy/mod_proxy_ftp.c @@ -1774,7 +1774,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, apr_rfc822_date(dates, r->request_time); apr_table_setn(r->headers_out, "Date", dates); - apr_table_setn(r->headers_out, "Server", ap_get_server_banner()); + apr_table_setn(r->headers_out, "Server", ap_get_server_description()); /* set content-type */ if (dirlisting) { diff --git a/server/core.c b/server/core.c index ad39613929..2656bd2cad 100644 --- a/server/core.c +++ b/server/core.c @@ -2679,12 +2679,13 @@ static int banner_locked = 0; static char *server_description = NULL; enum server_token_type { - SrvTk_MAJOR, /* eg: Apache/2 */ - SrvTk_MINOR, /* eg. Apache/2.0 */ - SrvTk_MINIMAL, /* eg: Apache/2.0.41 */ - SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */ - SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */ - SrvTk_PRODUCT_ONLY /* eg: Apache */ + SrvTk_MAJOR, /* eg: Apache/2 */ + SrvTk_MINOR, /* eg. Apache/2.0 */ + SrvTk_MINIMAL, /* eg: Apache/2.0.41 */ + SrvTk_OS, /* eg: Apache/2.0.41 (UNIX) */ + SrvTk_FULL, /* eg: Apache/2.0.41 (UNIX) PHP/4.2.2 FooBar/1.2b */ + SrvTk_PRODUCT_ONLY, /* eg: Apache */ + SrvTk_OFF /* eg: */ }; static enum server_token_type ap_server_tokens = SrvTk_FULL; @@ -2748,7 +2749,10 @@ AP_DECLARE(void) ap_add_version_component(apr_pool_t *pconf, const char *compone */ static void set_banner(apr_pool_t *pconf) { - if (ap_server_tokens == SrvTk_PRODUCT_ONLY) { + if (ap_server_tokens == SrvTk_OFF) { + ap_add_version_component(pconf, ""); + } + else if (ap_server_tokens == SrvTk_PRODUCT_ONLY) { ap_add_version_component(pconf, AP_SERVER_BASEPRODUCT); } else if (ap_server_tokens == SrvTk_MINIMAL) { @@ -2783,7 +2787,10 @@ static const char *set_serv_tokens(cmd_parms *cmd, void *dummy, return err; } - if (!strcasecmp(arg, "OS")) { + if (!strcasecmp(arg, "Off")) { + ap_server_tokens = SrvTk_OFF; + } + else if (!strcasecmp(arg, "OS")) { ap_server_tokens = SrvTk_OS; } else if (!strcasecmp(arg, "Min") || !strcasecmp(arg, "Minimal")) { @@ -3304,7 +3311,7 @@ AP_INIT_TAKE1("LogLevel", set_loglevel, NULL, RSRC_CONF, AP_INIT_TAKE1("NameVirtualHost", ap_set_name_virtual_host, NULL, RSRC_CONF, "A numeric IP address:port, or the name of a host"), AP_INIT_TAKE1("ServerTokens", set_serv_tokens, NULL, RSRC_CONF, - "Determine tokens displayed in the Server: header - Min(imal), OS or Full"), + "Determine tokens displayed in the Server: header - Min(imal), Major, Minor, Prod, OS, Off or Full"), AP_INIT_TAKE1("LimitRequestLine", set_limit_req_line, NULL, RSRC_CONF, "Limit on maximum size of an HTTP request line"), AP_INIT_TAKE1("LimitRequestFieldsize", set_limit_req_fieldsize, NULL, diff --git a/server/mpm_unix.c b/server/mpm_unix.c index 3333e18fe9..d2e7fbdbec 100644 --- a/server/mpm_unix.c +++ b/server/mpm_unix.c @@ -553,7 +553,7 @@ static apr_status_t dummy_connection(ap_pod_t *pod) * requests in their logs. */ srequest = apr_pstrcat(p, "OPTIONS * HTTP/1.0\r\nUser-Agent: ", - ap_get_server_banner(), + ap_get_server_description(), " (internal dummy connection)\r\n\r\n", NULL); /* Since some operating systems support buffering of data or entire