]> git.mxchange.org Git - flightgear.git/commitdiff
fgValidatePath: allow Nasal to read user-set scenery directories
authorRebecca N. Palmer <rebecca_palmer@zoho.com>
Sun, 22 Nov 2015 11:27:39 +0000 (11:27 +0000)
committerRebecca N. Palmer <rebecca_palmer@zoho.com>
Sun, 22 Nov 2015 11:27:39 +0000 (11:27 +0000)
(but not the Terrasync directory, as Nasal can change that)

src/Main/globals.cxx
src/Main/globals.hxx
src/Main/options.cxx
src/Main/util.cxx

index f0ce2354ee8f5268a4d7bedebb093093ea4deb4d..4425aabb09292b22bfae1e096721e4bdf1d851ca 100644 (file)
@@ -354,7 +354,7 @@ SGPath FGGlobals::find_data_dir(const std::string& pathSuffix) const
     return SGPath();
 }
 
-void FGGlobals::append_fg_scenery (const std::string &paths)
+void FGGlobals::append_fg_scenery (const std::string &paths, bool secure)
 {
     SGPropertyNode* sim = fgGetNode("/sim", true);
 
@@ -387,6 +387,9 @@ void FGGlobals::append_fg_scenery (const std::string &paths)
       // out, such that all three dirs are added. Unfortunately there's
       // no information as to why the change was made.
         fg_scenery.push_back(abspath.str());
+        if (secure) {
+          secure_fg_scenery.push_back(abspath.str());
+        }
 
         if (terrainDir.exists()) {
           fg_scenery.push_back(terrainDir.str());
@@ -414,6 +417,7 @@ void FGGlobals::append_fg_scenery (const std::string &paths)
 void FGGlobals::clear_fg_scenery()
 {
   fg_scenery.clear();
+  secure_fg_scenery.clear();
 }
 
 void FGGlobals::set_catalog_aircraft_path(const SGPath& path)
index cf8680ac3c9233d969df7322f374b8040a754659..f5a3f20d5dbedc0ceea03230fb0a731bf00d3ebd 100644 (file)
@@ -107,6 +107,7 @@ private:
 
     // Roots of FlightGear scenery tree
     string_list fg_scenery;
+    string_list secure_fg_scenery;
 
     std::string browser;
 
@@ -224,7 +225,16 @@ public:
     void set_fg_home (const std::string &home);
 
     inline const string_list &get_fg_scenery () const { return fg_scenery; }
-    void append_fg_scenery (const std::string &scenery);
+    inline const string_list &get_secure_fg_scenery () const { return secure_fg_scenery; }
+    /**
+     * Add a scenery directory
+     *
+     * secure = allow Nasal to read this directory; to avoid
+     * can-read-any-file security holes, do NOT set this on directories
+     * obtained from the property tree (e.g. /sim/terrasync/scenery-dir)
+     * or other Nasal-writable places
+     */ 
+    void append_fg_scenery (const std::string &scenery, bool secure = false);
 
     void clear_fg_scenery();
 
index cd9fe75db6c6617932f68eb309d125172b949f2d..00f2352a1736ebec59c2e63f59989594a3e1111e 100644 (file)
@@ -851,7 +851,7 @@ fgOptRoc( const char *arg )
 static int
 fgOptFgScenery( const char *arg )
 {
-    globals->append_fg_scenery(arg);
+    globals->append_fg_scenery(arg, true);
     return FG_OPTIONS_OK;
 }
 
@@ -2278,7 +2278,7 @@ OptionResult Options::processOptions()
 // now options are process, do supplemental fixup
   const char *envp = ::getenv( "FG_SCENERY" );
   if (envp) {
-    globals->append_fg_scenery(envp);
+    globals->append_fg_scenery(envp, true);
   }
 
 // download dir fix-up
index 65983ce045de3686f0c9b90b01239a9c7d40eb58..6bc4ddb50f36093591778d1ee750c91bb7a56167 100644 (file)
@@ -78,8 +78,6 @@ static string_list write_allowed_paths;
 /**
  * Allowed paths here are absolute, and may contain _one_ *,
  * which matches any string
- * FG_SCENERY is deliberately not allowed, as it would make
- * /sim/terrasync/scenery-dir a security hole
  */
 void fgInitAllowedPaths()
 {
@@ -104,16 +102,25 @@ void fgInitAllowedPaths()
     read_allowed_paths.push_back(fg_root + sep + "*");
     read_allowed_paths.push_back(fg_home + sep + "*");
     string_list const aircraft_paths = globals->get_aircraft_paths();
-    for( string_list::const_iterator it = aircraft_paths.begin();
-                                     it != aircraft_paths.end();
-                                   ++it )
+    string_list const scenery_paths = globals->get_secure_fg_scenery();
+    // not plain fg_scenery, to avoid making
+    // /sim/terrasync/scenery-dir a security hole
+
+    for( string_list::const_iterator it = aircraft_paths.begin();;++it )
     {
+      if (it == aircraft_paths.end()) {
+        it = scenery_paths.begin();
+      }
+      if (it == scenery_paths.end()) {
+        break; // here rather than in the loop condition because
+               // scenery_paths may be empty
+      }
       // if we get the initialization order wrong, better to have an
       // obvious error than a can-read-everything security hole...
         if (it->empty() || fg_root.empty() || fg_home.empty()){
             flightgear::fatalMessageBox("Nasal initialization error",
-                                    "Empty string in FG_ROOT, FG_HOME or FG_AIRCRAFT",
-                                    "or fgInitAllowedPaths() called too early");
+               "Empty string in FG_ROOT, FG_HOME, FG_AIRCRAFT or FG_SCENERY",
+                                 "or fgInitAllowedPaths() called too early");
             exit(-1);
         }
         read_allowed_paths.push_back(SGPath(*it).realpath() + sep + "*");