use same path validation process for fgcommands "load", "save",
"loadxml", ans "savexml" as is used for io.open(). This is still Nasal based for now. See $FG_ROOT/Nasal/io.nas.
This commit is contained in:
parent
ce7f695ea2
commit
76a13e689d
4 changed files with 74 additions and 24 deletions
|
@ -320,16 +320,23 @@ do_resume (const SGPropertyNode * arg)
|
||||||
static bool
|
static bool
|
||||||
do_load (const SGPropertyNode * arg)
|
do_load (const SGPropertyNode * arg)
|
||||||
{
|
{
|
||||||
const string &file = arg->getStringValue("file", "fgfs.sav");
|
const string &file = arg->getStringValue("file", "fgfs.sav");
|
||||||
ifstream input(file.c_str());
|
|
||||||
if (input.good() && fgLoadFlight(input)) {
|
if (!fgValidatePath(file.c_str(), false)) {
|
||||||
input.close();
|
SG_LOG(SG_IO, SG_ALERT, "load: reading '" << file << "' denied "
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "Restored flight from " << file);
|
"(unauthorized access)");
|
||||||
return true;
|
return false;
|
||||||
} else {
|
}
|
||||||
SG_LOG(SG_INPUT, SG_WARN, "Cannot load flight from " << file);
|
|
||||||
return false;
|
ifstream input(file.c_str());
|
||||||
}
|
if (input.good() && fgLoadFlight(input)) {
|
||||||
|
input.close();
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "Restored flight from " << file);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_INPUT, SG_WARN, "Cannot load flight from " << file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -342,18 +349,25 @@ do_load (const SGPropertyNode * arg)
|
||||||
static bool
|
static bool
|
||||||
do_save (const SGPropertyNode * arg)
|
do_save (const SGPropertyNode * arg)
|
||||||
{
|
{
|
||||||
const string &file = arg->getStringValue("file", "fgfs.sav");
|
const string &file = arg->getStringValue("file", "fgfs.sav");
|
||||||
bool write_all = arg->getBoolValue("write-all", false);
|
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "Saving flight");
|
if (!fgValidatePath(file.c_str(), false)) {
|
||||||
ofstream output(file.c_str());
|
SG_LOG(SG_IO, SG_ALERT, "save: reading '" << file << "' denied "
|
||||||
if (output.good() && fgSaveFlight(output, write_all)) {
|
"(unauthorized access)");
|
||||||
output.close();
|
return false;
|
||||||
SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file);
|
}
|
||||||
return true;
|
|
||||||
} else {
|
bool write_all = arg->getBoolValue("write-all", false);
|
||||||
SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight to " << file);
|
SG_LOG(SG_INPUT, SG_INFO, "Saving flight");
|
||||||
return false;
|
ofstream output(file.c_str());
|
||||||
}
|
if (output.good() && fgSaveFlight(output, write_all)) {
|
||||||
|
output.close();
|
||||||
|
SG_LOG(SG_INPUT, SG_INFO, "Saved flight to " << file);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_INPUT, SG_ALERT, "Cannot save flight to " << file);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1336,6 +1350,12 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
|
||||||
if (file.extension() != "xml")
|
if (file.extension() != "xml")
|
||||||
file.concat(".xml");
|
file.concat(".xml");
|
||||||
|
|
||||||
|
if (!fgValidatePath(file.c_str(), false)) {
|
||||||
|
SG_LOG(SG_IO, SG_ALERT, "loadxml: reading '" << file.str() << "' denied "
|
||||||
|
"(unauthorized access)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SGPropertyNode *targetnode;
|
SGPropertyNode *targetnode;
|
||||||
if (arg->hasValue("targetnode"))
|
if (arg->hasValue("targetnode"))
|
||||||
targetnode = fgGetNode(arg->getStringValue("targetnode"), true);
|
targetnode = fgGetNode(arg->getStringValue("targetnode"), true);
|
||||||
|
@ -1349,7 +1369,7 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1376,6 +1396,12 @@ do_save_xml_from_proptree(const SGPropertyNode * arg)
|
||||||
if (file.extension() != "xml")
|
if (file.extension() != "xml")
|
||||||
file.concat(".xml");
|
file.concat(".xml");
|
||||||
|
|
||||||
|
if (!fgValidatePath(file.c_str(), true)) {
|
||||||
|
SG_LOG(SG_IO, SG_ALERT, "savexml: writing to '" << file.str() << "' denied "
|
||||||
|
"(unauthorized access)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
SGPropertyNode *sourcenode;
|
SGPropertyNode *sourcenode;
|
||||||
if (arg->hasValue("sourcenode"))
|
if (arg->hasValue("sourcenode"))
|
||||||
sourcenode = fgGetNode(arg->getStringValue("sourcenode"), true);
|
sourcenode = fgGetNode(arg->getStringValue("sourcenode"), true);
|
||||||
|
|
|
@ -81,6 +81,7 @@
|
||||||
#include "renderer.hxx"
|
#include "renderer.hxx"
|
||||||
#include "splash.hxx"
|
#include "splash.hxx"
|
||||||
#include "main.hxx"
|
#include "main.hxx"
|
||||||
|
#include "util.hxx"
|
||||||
|
|
||||||
|
|
||||||
static double real_delta_time_sec = 0.0;
|
static double real_delta_time_sec = 0.0;
|
||||||
|
@ -984,6 +985,7 @@ bool fgMainInit( int argc, char **argv ) {
|
||||||
string_list *col = new string_list;
|
string_list *col = new string_list;
|
||||||
globals->set_channel_options_list( col );
|
globals->set_channel_options_list( col );
|
||||||
|
|
||||||
|
fgValidatePath("", false); // initialize static variables
|
||||||
upper_case_property("/sim/presets/airport-id");
|
upper_case_property("/sim/presets/airport-id");
|
||||||
upper_case_property("/sim/presets/runway");
|
upper_case_property("/sim/presets/runway");
|
||||||
upper_case_property("/sim/tower/airport-id");
|
upper_case_property("/sim/tower/airport-id");
|
||||||
|
|
|
@ -147,7 +147,7 @@ fgGetLowPass (double current, double target, double timeratio)
|
||||||
|
|
||||||
|
|
||||||
string
|
string
|
||||||
fgUnescape(const char *s)
|
fgUnescape (const char *s)
|
||||||
{
|
{
|
||||||
string r;
|
string r;
|
||||||
while (*s) {
|
while (*s) {
|
||||||
|
@ -197,5 +197,19 @@ fgUnescape(const char *s)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *fgValidatePath (const char *str, bool write)
|
||||||
|
{
|
||||||
|
static SGPropertyNode_ptr r, w;
|
||||||
|
if (!r) {
|
||||||
|
r = fgGetNode("/sim/paths/validate/read", true);
|
||||||
|
w = fgGetNode("/sim/paths/validate/write", true);
|
||||||
|
}
|
||||||
|
SGPropertyNode *prop = write ? w : r;
|
||||||
|
prop->setStringValue(str);
|
||||||
|
const char *result = prop->getStringValue();
|
||||||
|
return result[0] ? result : 0;
|
||||||
|
}
|
||||||
|
|
||||||
// end of util.cxx
|
// end of util.cxx
|
||||||
|
|
||||||
|
|
|
@ -83,4 +83,12 @@ extern double fgGetLowPass (double current, double target, double timeratio);
|
||||||
extern std::string fgUnescape (const char *str);
|
extern std::string fgUnescape (const char *str);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validation listener interface for io.nas, used by fgcommands.
|
||||||
|
* @param path Path to be validated
|
||||||
|
* @param write True for write operations and false for read operations.
|
||||||
|
* @return The validated path on success or 0 if access denied.
|
||||||
|
*/
|
||||||
|
extern const char *fgValidatePath (const char *path, bool write);
|
||||||
|
|
||||||
#endif // __UTIL_HXX
|
#endif // __UTIL_HXX
|
||||||
|
|
Loading…
Add table
Reference in a new issue