mirror of
https://github.com/apache/httpd.git
synced 2025-08-06 11:06:17 +00:00
add UNCList directive on Windows
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1918549 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@ -5318,6 +5318,33 @@ recognized methods to modules.</p>
|
|||||||
</usage>
|
</usage>
|
||||||
</directivesynopsis>
|
</directivesynopsis>
|
||||||
|
|
||||||
|
<directivesynopsis>
|
||||||
|
<name>UNCList</name>
|
||||||
|
<description>Controls what UNC host names can be accessed by the server
|
||||||
|
</description>
|
||||||
|
<syntax>UNCList<var>hostname</var> ...</syntax>
|
||||||
|
<default>unset</default>
|
||||||
|
<contextlist><context>server config</context>
|
||||||
|
</contextlist>
|
||||||
|
<compatibility>Added in 2.4.60, Windows only.</compatibility>
|
||||||
|
|
||||||
|
<usage>
|
||||||
|
<p> During request processing, requests to access a filesystem path that
|
||||||
|
resolves to a UNC path will fail unless the hostname in the UNC path
|
||||||
|
has been specified by this directive. The intent is to limit access to
|
||||||
|
paths derived from untrusted inputs.</p>
|
||||||
|
|
||||||
|
<note type="warning"><title>Security</title>
|
||||||
|
UNC paths accessed outside of request processing, such as during startup,
|
||||||
|
are not checked against the hosts configured with this directive.</p>
|
||||||
|
</note>
|
||||||
|
</usage>
|
||||||
|
</directivesynopsis>
|
||||||
|
|
||||||
|
|
||||||
|
UNCList
|
||||||
|
|
||||||
|
|
||||||
<directivesynopsis>
|
<directivesynopsis>
|
||||||
<name>MergeTrailers</name>
|
<name>MergeTrailers</name>
|
||||||
<description>Determines whether trailers are merged into headers</description>
|
<description>Determines whether trailers are merged into headers</description>
|
||||||
|
@ -771,6 +771,9 @@ typedef struct {
|
|||||||
apr_int32_t flush_max_pipelined;
|
apr_int32_t flush_max_pipelined;
|
||||||
unsigned int strict_host_check;
|
unsigned int strict_host_check;
|
||||||
unsigned int merge_slashes;
|
unsigned int merge_slashes;
|
||||||
|
#ifdef WIN32
|
||||||
|
apr_array_header_t *unc_list;
|
||||||
|
#endif
|
||||||
} core_server_config;
|
} core_server_config;
|
||||||
|
|
||||||
/* for AddOutputFiltersByType in core.c */
|
/* for AddOutputFiltersByType in core.c */
|
||||||
|
@ -2847,6 +2847,31 @@ AP_DECLARE(const char *)ap_dir_fnmatch(ap_dir_match_t *w, const char *path,
|
|||||||
*/
|
*/
|
||||||
AP_DECLARE(int) ap_is_chunked(apr_pool_t *p, const char *line);
|
AP_DECLARE(int) ap_is_chunked(apr_pool_t *p, const char *line);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* apr_filepath_merge with an allow-list
|
||||||
|
* Merge additional file path onto the previously processed rootpath
|
||||||
|
* @param newpath the merged paths returned
|
||||||
|
* @param rootpath the root file path (NULL uses the current working path)
|
||||||
|
* @param addpath the path to add to the root path
|
||||||
|
* @param flags the desired APR_FILEPATH_ rules to apply when merging
|
||||||
|
* @param p the pool to allocate the new path string from
|
||||||
|
* @remark if the flag APR_FILEPATH_TRUENAME is given, and the addpath
|
||||||
|
* contains wildcard characters ('*', '?') on platforms that don't support
|
||||||
|
* such characters within filenames, the paths will be merged, but the
|
||||||
|
* result code will be APR_EPATHWILD, and all further segments will not
|
||||||
|
* reflect the true filenames including the wildcard and following segments.
|
||||||
|
*/
|
||||||
|
AP_DECLARE(apr_status_t) ap_filepath_merge(char **newpath,
|
||||||
|
const char *rootpath,
|
||||||
|
const char *addpath,
|
||||||
|
apr_int32_t flags,
|
||||||
|
apr_pool_t *p);
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define apr_filepath_merge ap_filepath_merge
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
101
server/core.c
101
server/core.c
@ -4678,6 +4678,25 @@ static const char *set_merge_trailers(cmd_parms *cmd, void *dummy, int arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
static const char *set_unc_list(cmd_parms *cmd, void *d_, int argc, char *const argv[])
|
||||||
|
{
|
||||||
|
core_server_config *sconf = ap_get_core_module_config(cmd->server->module_config);
|
||||||
|
int i;
|
||||||
|
const char *err;
|
||||||
|
|
||||||
|
if ((err = ap_check_cmd_context(cmd, NOT_IN_VIRTUALHOST)) != NULL)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
sconf->unc_list = apr_array_make(cmd->pool, argc, sizeof(char *));
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
*(char **)apr_array_push(sconf->unc_list) = apr_pstrdup(cmd->pool, argv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* Note --- ErrorDocument will now work from .htaccess files.
|
/* Note --- ErrorDocument will now work from .htaccess files.
|
||||||
* The AllowOverride of Fileinfo allows webmasters to turn it off
|
* The AllowOverride of Fileinfo allows webmasters to turn it off
|
||||||
*/
|
*/
|
||||||
@ -4781,6 +4800,10 @@ AP_INIT_TAKE1("FlushMaxThreshold", set_flush_max_threshold, NULL, RSRC_CONF,
|
|||||||
AP_INIT_TAKE1("FlushMaxPipelined", set_flush_max_pipelined, NULL, RSRC_CONF,
|
AP_INIT_TAKE1("FlushMaxPipelined", set_flush_max_pipelined, NULL, RSRC_CONF,
|
||||||
"Maximum number of pipelined responses (pending) above which they are "
|
"Maximum number of pipelined responses (pending) above which they are "
|
||||||
"flushed to the network"),
|
"flushed to the network"),
|
||||||
|
#ifdef WIN32
|
||||||
|
AP_INIT_TAKE_ARGV("UNCList", set_unc_list, NULL, RSRC_CONF,
|
||||||
|
"Controls what UNC hosts may be looked up"),
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Old server config file commands */
|
/* Old server config file commands */
|
||||||
|
|
||||||
@ -6001,6 +6024,84 @@ AP_CORE_DECLARE(apr_status_t) ap_get_pollfd_from_conn(conn_rec *c,
|
|||||||
return ap_run_get_pollfd_from_conn(c, pfd, ptimeout);
|
return ap_run_get_pollfd_from_conn(c, pfd, ptimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
static apr_status_t check_unc(const char *path, apr_pool_t *p)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char *s, *teststring;
|
||||||
|
apr_status_t rv = APR_EACCES;
|
||||||
|
core_server_config *sconf = NULL;
|
||||||
|
|
||||||
|
if (!ap_server_conf) {
|
||||||
|
return APR_SUCCESS; /* this early, if we have a UNC, it's specified by an admin */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path || (path != ap_strstr_c(path, "\\\\") &&
|
||||||
|
path != ap_strstr_c(path, "//"))) {
|
||||||
|
return APR_SUCCESS; /* not a UNC */
|
||||||
|
}
|
||||||
|
|
||||||
|
sconf = ap_get_core_module_config(ap_server_conf->module_config);
|
||||||
|
s = teststring = apr_pstrdup(p, path);
|
||||||
|
*s++ = '/';
|
||||||
|
*s++ = '/';
|
||||||
|
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
|
||||||
|
"ap_filepath_merge: check converted path %s allowed %d",
|
||||||
|
teststring,
|
||||||
|
sconf->unc_list ? sconf->unc_list->nelts : 0);
|
||||||
|
|
||||||
|
for (i = 0; sconf->unc_list && i < sconf->unc_list->nelts; i++) {
|
||||||
|
char *configured_unc = ((char **)sconf->unc_list->elts)[i];
|
||||||
|
apr_uri_t uri;
|
||||||
|
if (APR_SUCCESS == apr_uri_parse(p, teststring, &uri) &&
|
||||||
|
(uri.hostinfo == NULL ||
|
||||||
|
!ap_cstr_casecmp(uri.hostinfo, configured_unc))) {
|
||||||
|
rv = APR_SUCCESS;
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
|
||||||
|
"ap_filepath_merge: match %s %s",
|
||||||
|
uri.hostinfo, configured_unc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_TRACE4, 0, ap_server_conf,
|
||||||
|
"ap_filepath_merge: no match %s %s", uri.hostinfo,
|
||||||
|
configured_unc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rv != APR_SUCCESS) {
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_ERR, rv, ap_server_conf, APLOGNO(10504)
|
||||||
|
"ap_filepath_merge: UNC path %s not allowed by UNCList", teststring);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
AP_DECLARE(apr_status_t) ap_filepath_merge(char **newpath,
|
||||||
|
const char *rootpath,
|
||||||
|
const char *addpath,
|
||||||
|
apr_int32_t flags,
|
||||||
|
apr_pool_t *p)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
apr_status_t rv;
|
||||||
|
|
||||||
|
if (APR_SUCCESS != (rv = check_unc(rootpath, p))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
if (APR_SUCCESS != (rv = check_unc(addpath, p))) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#undef apr_filepath_merge
|
||||||
|
#endif
|
||||||
|
return apr_filepath_merge(newpath, rootpath, addpath, flags, p);
|
||||||
|
#ifdef WIN32
|
||||||
|
#define apr_filepath_merge ap_filepath_merge
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void register_hooks(apr_pool_t *p)
|
static void register_hooks(apr_pool_t *p)
|
||||||
{
|
{
|
||||||
errorlog_hash = apr_hash_make(p);
|
errorlog_hash = apr_hash_make(p);
|
||||||
|
Reference in New Issue
Block a user