foo_httpcontrol: More strict Allowed paths checking; Fixed excessive error messages for Browse command; 0.97.17 released.
This commit is contained in:
@@ -95,7 +95,7 @@
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<IgnoreSpecificDefaultLibraries>%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
|
||||
<AdditionalDependencies>$(SolutionDir)lib/foobar2000/shared/shared.lib;$(SolutionDir)lib/atlmfc/lib/atls.lib;shlwapi.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<Version>0.97.15</Version>
|
||||
<Version>0.97.17</Version>
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
<ModuleDefinitionFile>
|
||||
</ModuleDefinitionFile>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>foo_httpcontrol 0.97.16 13 Jan 2016</h2>
|
||||
<h2>foo_httpcontrol 0.97.17 14 Jan 2016</h2>
|
||||
<p><a href="https://bitbucket.org/oblikoamorale/foo_httpcontrol/wiki/Home">https://bitbucket.org/oblikoamorale/foo_httpcontrol/wiki/Home</a></p>
|
||||
|
||||
<h2 id="warn">Warning/disclaimer: this software comes without any warranties at all. It is still in the very early development stage, and so on, and so forth, blah-blah-blah.
|
||||
@@ -75,11 +75,12 @@ customizing any template you are using, or even writing your very own one.</p>
|
||||
<li>Opens component page in default browser. Button is inactive if server/listener isn't started.</li>
|
||||
<li>Limit access to component by setting the allowed IP address. Connections initiated from other addresses will be discarded. Setting this to 0.0.0.0 allows all connections.</li>
|
||||
<li>Limit access to component by defining a login/password pair. Untick to disable passwords.</li>
|
||||
<li>Built-in file browser can be limited to certain paths of your file system. It is useful to simplify the browsing process or hide your secret files from prying eyes. For example, setting Allowed paths to d:\music|c:\temp\music|e:\ permits browsing only in these three file system branches.</li>
|
||||
<li>Built-in file browser can be limited to certain paths of your file system. It is useful to simplify the browsing process or hide your secret files from prying eyes. For example, setting Allowed paths to d:\music|c:\temp\music|e:\ permits browsing only in these three file system branches.
|
||||
To additionally access Microsoft Network, add 'Network:' and '\\' (without quotes) to allowed paths.</li>
|
||||
<li>You can specify additional file extensions to be treated as playable files by built-in file browser. It is required for opening archives containing playable files.</li>
|
||||
<li>Ignore files with specific extensions in file browser.</li>
|
||||
<li>Urls of specified protocols are allowed to be enqueued by Browse command. Enables enqueueing of urls handled by 3rd party components like foo_youtube (3dydfy protocol).<br>
|
||||
Suggested value setting: http|https</li>
|
||||
Suggested value: http|https</li>
|
||||
<li>Removes all files which foobar2000 core considers unplayable from built-in file browser.</li>
|
||||
<li>Specifies path where component will look for template files. Pressing Open opens specified or default directory in Explorer. If not sure, leave it blank. </li>
|
||||
<li>Enables gzip compression of component output. Enabling it is usually harmless and quite beneficial as component generates a lot of text which is very compressible. Disable if you are using some funky browser and having unexpected problems.</li>
|
||||
@@ -94,6 +95,12 @@ Don't forget to press Apply or your changes won't have any effect until fb2k is
|
||||
<a href="http://www.hydrogenaudio.org/forums/index.php?showtopic=62218">http://www.hydrogenaudio.org/forums/index.php?showtopic=62218</a></p>
|
||||
|
||||
<h2>Changes history 2016</h2>
|
||||
<p>v0.97.17 14 Jan</p>
|
||||
<ul>
|
||||
<li>fix: More strict Allowed paths checking. Now, to be able to access Microsoft Network when operating in Allowed paths mode, add 'Network:' and '\\' (without quotes) to Allowed paths value;<br>
|
||||
<li>fix: Excessive error messages for Browse command;</li>
|
||||
</ul>
|
||||
|
||||
<p>v0.97.16 13 Jan</p>
|
||||
<ul>
|
||||
<li>add: Allowed protocols GUI setting: urls of specified protocols are allowed to be enqueued by Browse command. Previously the only hardcoded protocol was http. New setting also enables enqueueing of urls handled by 3rd party components like foo_youtube (3dydfy protocol).<br>
|
||||
@@ -101,7 +108,6 @@ Suggested value setting: http|https</li>
|
||||
<li>add: Meaningful console error messages when Browse command refuses to add specified file / location;</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>Changes history 2014</h2>
|
||||
<p>v0.97.15 02 Mar</p>
|
||||
<ul>
|
||||
@@ -449,6 +455,11 @@ example: ?cmd=PlayingCommand&param1=Playback%20Statistics%2FRating%2F3</li>
|
||||
cmd=SetFocus<br/>
|
||||
param1=item starting from 0</li>
|
||||
|
||||
<li>Get directory file list<br/>
|
||||
cmd=Browse<br/>
|
||||
param1=urlencoded directory path with trailing backslash<br/>
|
||||
</li>
|
||||
|
||||
<li>Enqueue single file or url<br/>
|
||||
cmd=Browse<br/>
|
||||
param1=urlencoded file path / url</li>
|
||||
|
||||
@@ -825,35 +825,64 @@ namespace control
|
||||
if (httpc::enqueueing)
|
||||
return false;
|
||||
|
||||
pfc::string8 ¶m1 = cmd->get_param(0);
|
||||
pfc::string8 ¶m2 = cmd->get_param(1);
|
||||
pfc::string8 param1 = cmd->get_param(cmd->E_PARAM1);
|
||||
pfc::string8 param2 = cmd->get_param(cmd->E_PARAM2);
|
||||
|
||||
foo_browsefiles browser;
|
||||
list_t<const char *> files; // files/dirs to be enqueued
|
||||
pfc::string8 filename = param1;
|
||||
|
||||
bool is_dir = false;
|
||||
bool is_dir_allowed = false;
|
||||
bool is_file = false;
|
||||
bool is_url = false;
|
||||
|
||||
// if no path specified, use last browse directory
|
||||
if (param1.get_length() == 0)
|
||||
foo_error("param1 cannot be empty");
|
||||
param1 = cfg.misc.last_browse_dir;
|
||||
|
||||
// check if param2 is a valid command
|
||||
if (param2.get_length() > 0 &&
|
||||
(strcmp(param2, "EnqueueDir") != 0 && strcmp(param2, "EnqueueDirSubdirs") != 0))
|
||||
foo_error(pfc::string8() << "unsupported param2 value: \"" << param2 << "\"");
|
||||
foo_error(pfc::string8() << "ignoring param2: \"" << param2 << "\": unknown mode");
|
||||
|
||||
if (( httpc::is_extension_registered(filename) != pfc::infinite_size || httpc::is_protocol_allowed(filename) ) && param2.get_length() == 0) // adding a single file
|
||||
files.add_item(filename);
|
||||
// assuming path is a directory if ends with separator
|
||||
// " " is a root shortcut, also counts as a directory
|
||||
if (param1.ends_with('\\') || strcmp(param1, " ") == 0)
|
||||
is_dir = true;
|
||||
|
||||
if (httpc::is_protocol_allowed(param1))
|
||||
is_url = true;
|
||||
|
||||
if (!is_dir && !is_url)
|
||||
is_file = true;
|
||||
|
||||
if (is_dir || is_file)
|
||||
{
|
||||
is_dir_allowed = httpc::is_path_allowed(param1);
|
||||
if (!is_dir_allowed)
|
||||
foo_error(pfc::string8() << "ignoring param1: \"" << param1 << "\": doesn't match Allowed paths");
|
||||
}
|
||||
|
||||
// try to enqueue param1 if is a file with allowed extension, or url with allowed protocol
|
||||
if ((is_file && httpc::is_extension_registered(param1) != pfc::infinite_size || is_url)
|
||||
&& param2.get_length() == 0) // add a file / location
|
||||
{
|
||||
files.add_item(param1);
|
||||
}
|
||||
else
|
||||
if (param2.get_length() == 0)
|
||||
foo_error(pfc::string8() << "skipping \"" << filename << "\": unrecognized extension or not allowed protocol");
|
||||
is_file = false;
|
||||
|
||||
if (param1.get_length() != 0 && param2.get_length() != 0)
|
||||
if (!is_dir && !is_file && !is_url)
|
||||
foo_error(pfc::string8() << "ignoring param1: \"" << param1 << "\": not a directory, unrecognized extension or not allowed protocol");
|
||||
|
||||
if (is_dir && is_dir_allowed && param2.get_length() != 0)
|
||||
{
|
||||
if (strcmp(param2, "EnqueueDirSubdirs") == 0) // adding a nested directory
|
||||
{
|
||||
files.add_item(filename);
|
||||
}
|
||||
files.add_item(param1);
|
||||
|
||||
if (strcmp(param2, "EnqueueDir") == 0) // adding a directory without nesting;
|
||||
{
|
||||
browser.browse(const_cast<char *>(filename.operator const char *()));
|
||||
foo_browsefiles browser;
|
||||
browser.browse(const_cast<char *>(param1.operator const char *()));
|
||||
|
||||
t_size l = browser.entries.get_count();
|
||||
for(unsigned int i = 0; i < l; ++i)
|
||||
|
||||
@@ -51,7 +51,7 @@ void config_main::reset()
|
||||
gzip_enable = false;
|
||||
extra_formats = "zip|rar";
|
||||
ignored_formats = "";
|
||||
allowed_protocols = "http|https|3dydfy";
|
||||
allowed_protocols = "http|https";
|
||||
}
|
||||
|
||||
void config_main::get_data_raw(stream_writer * p_stream,abort_callback & p_abort)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
DECLARE_COMPONENT_VERSION(
|
||||
"HTTP Control",
|
||||
"0.97.16",
|
||||
"0.97.17",
|
||||
"control foobar2000 via http "__DATE__)
|
||||
|
||||
VALIDATE_COMPONENT_FILENAME("foo_httpcontrol.dll");
|
||||
|
||||
@@ -558,49 +558,30 @@ void foo_httpserv::process_request()
|
||||
else
|
||||
if (strcmp(cmd, "Browse") == 0)
|
||||
{
|
||||
if (param1.get_length() == 0)
|
||||
param1 = cfg.misc.last_browse_dir;
|
||||
|
||||
if (cfg.restrict_to_path_list.get_count()) // allowing to browse only specified dirs (if any)
|
||||
{
|
||||
bool isallowed = false;
|
||||
|
||||
if (param1.get_length() > 0)
|
||||
{
|
||||
pfc::string tmp2(param1.toString());
|
||||
t_size l = cfg.restrict_to_path_list.get_count();
|
||||
|
||||
if ((tmp2.indexOf("..\\") == ~0) && (tmp2.indexOf("../") == ~0)) // check for stuff like d:\music\..\..\..\temp
|
||||
for (size_t i = 0; i < l; ++i)
|
||||
{
|
||||
pfc::string8_fast_aggressive tmp(param1);
|
||||
tmp.truncate(cfg.restrict_to_path_list[i].get_length());
|
||||
|
||||
if (pfc::stringCompareCaseInsensitive(tmp, cfg.restrict_to_path_list[i]) == 0)
|
||||
{
|
||||
isallowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! isallowed)
|
||||
param1 = " ";
|
||||
}
|
||||
|
||||
// strip file name from path if the user clicked on file
|
||||
bool is_file = false;
|
||||
|
||||
bool is_url = httpc::is_protocol_allowed(param1);
|
||||
|
||||
if (param1.length() > 3 && param1[param1.length()-1] != '\\')
|
||||
// if no path specified or adding url, use last browse directory
|
||||
if (param1.get_length() == 0 || is_url)
|
||||
param1 = cfg.misc.last_browse_dir;
|
||||
|
||||
if (!is_url)
|
||||
if (!httpc::is_path_allowed(param1)) // allowing to browse only specified dirs (if any)
|
||||
param1 = cfg.misc.last_browse_dir;
|
||||
|
||||
if (param1.length() > 3 && !param1.ends_with('\\') && !is_url)
|
||||
{
|
||||
char *stripped_filename = foo_browsefiles::get_path_parent((char *)param1.operator const char *());
|
||||
if (stripped_filename)
|
||||
|
||||
if (stripped_filename && strlen(stripped_filename) > 2)
|
||||
{
|
||||
param1 = stripped_filename;
|
||||
delete[] stripped_filename;
|
||||
}
|
||||
else // invalid request, displaying root
|
||||
param1 = " ";
|
||||
else // invalid request, displaying last browse dir
|
||||
param1 = cfg.misc.last_browse_dir;
|
||||
|
||||
is_file = true;
|
||||
}
|
||||
@@ -611,7 +592,7 @@ void foo_httpserv::process_request()
|
||||
httpc::ui::parse_buffer_browser(param1, show, timer);
|
||||
}
|
||||
|
||||
if (param1.get_length() != 0 && !is_file)
|
||||
if (param1.get_length() != 0 && !is_file && !is_url)
|
||||
cfg.misc.last_browse_dir = param1;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -63,11 +63,17 @@ public:
|
||||
class foo_httpserver_command
|
||||
{
|
||||
public:
|
||||
enum commands {
|
||||
E_PARAM1=0,
|
||||
E_PARAM2=1,
|
||||
E_PARAM3=2
|
||||
};
|
||||
|
||||
foo_httpserver_command() { };
|
||||
foo_httpserver_command(pfc::string8 cmd, pfc::string8 param1, pfc::string8 param2, pfc::string8 param3) : m_cmd(cmd), m_param1(param1), m_param2(param2), m_param3(param3) { };
|
||||
|
||||
pfc::string8 &get_command() { return m_cmd; }
|
||||
pfc::string8 &get_param(int index)
|
||||
pfc::string8 get_command() { return m_cmd; }
|
||||
pfc::string8 get_param(int index)
|
||||
{
|
||||
switch(index) {
|
||||
case 0: return m_param1;
|
||||
|
||||
@@ -580,6 +580,30 @@ namespace httpc {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_path_allowed(const char *path)
|
||||
{
|
||||
if (cfg.restrict_to_path_list.get_count()) // allowing to browse only specified dirs (if any)
|
||||
{
|
||||
if (strlen(path) > 0)
|
||||
{
|
||||
t_size l = cfg.restrict_to_path_list.get_count();
|
||||
|
||||
if (strstr(path, "..\\") == NULL && strstr(path, "../") == NULL) // check for stuff like d:\music\..\..\..\temp
|
||||
for (size_t i = 0; i < l; ++i)
|
||||
{
|
||||
pfc::string8 tmp(path);
|
||||
tmp.truncate(cfg.restrict_to_path_list[i].get_length());
|
||||
|
||||
if (pfc::stringCompareCaseInsensitive(tmp, cfg.restrict_to_path_list[i]) == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void get_registered_extensions()
|
||||
{
|
||||
extensions.remove_all();
|
||||
@@ -706,6 +730,9 @@ namespace httpc {
|
||||
{
|
||||
cfg.restrict_to_path_list.remove_all();
|
||||
get_list(cfg.main.restrict_to_path, cfg.restrict_to_path_list, '|', true);
|
||||
|
||||
if (cfg.restrict_to_path_list.get_count())
|
||||
cfg.restrict_to_path_list.add_item(" ");
|
||||
}
|
||||
|
||||
void control_credentials_auth_hash_update()
|
||||
|
||||
@@ -126,6 +126,7 @@ namespace httpc {
|
||||
extern void set_allowed_protocols();
|
||||
extern size_t is_extension_registered(const char *path); // infininte if not registered, list index elsewere
|
||||
extern bool is_protocol_allowed(const char *path);
|
||||
extern bool is_path_allowed(const char *path);
|
||||
|
||||
extern void choose_srv_home_dir();
|
||||
extern void build_restrict_to_path_list();
|
||||
|
||||
Reference in New Issue
Block a user