summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Melcher <git@matthiasm.com>2019-12-31 18:30:04 +0100
committerMatthias Melcher <git@matthiasm.com>2019-12-31 18:30:04 +0100
commitc0237a1f045d14a54fe9a999543cb83385ac7dd6 (patch)
tree0ea97f9bd687167bdb86578acc23d9066481b514
parent0a23d7fe6e3a7b8000dcc6e7c4826e894f184079 (diff)
Limiting file access for Fl_Preferences.
Added Fl_Preferences::file_access() and various flags that make it possible to limit or completely deny file access to the preferences system, either for the core library or for the application or both.
-rw-r--r--FL/Fl_Preferences.H45
-rw-r--r--src/Fl.cxx6
-rw-r--r--src/Fl_File_Chooser.cxx2
-rw-r--r--src/Fl_File_Chooser.fl2
-rw-r--r--src/Fl_Preferences.cxx81
-rw-r--r--src/drivers/Android/Fl_Android_System_Driver.cxx4
-rw-r--r--src/drivers/Darwin/Fl_Darwin_System_Driver.cxx2
-rw-r--r--src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx2
-rw-r--r--src/drivers/X11/Fl_X11_System_Driver.cxx2
-rw-r--r--src/print_panel.cxx5
10 files changed, 133 insertions, 18 deletions
diff --git a/FL/Fl_Preferences.H b/FL/Fl_Preferences.H
index af2c8fd87..45717265a 100644
--- a/FL/Fl_Preferences.H
+++ b/FL/Fl_Preferences.H
@@ -73,8 +73,12 @@ public:
Define the scope of the preferences.
*/
enum Root {
- SYSTEM=0, ///< Preferences are used system-wide
- USER ///< Preferences apply only to the current user
+ SYSTEM = 0, ///< Preferences are used system-wide
+ USER, ///< Preferences apply only to the current user
+ ROOT_MASK = 0xFF, //< maks for the values above
+ CORE = 0x100, ///< OR'd by FLTK to read and write core library preferences and options
+ CORE_SYSTEM = CORE|SYSTEM,
+ CORE_USER = CORE|USER
};
/**
@@ -88,6 +92,41 @@ public:
static const char *newUUID();
+ /** Set this, if no call to Fl_Preferences shall access the file sytem
+ @see Fl_Preferences::file_access(unsigned int)
+ @see Fl_Preferences::file_access()
+ */
+ static const unsigned int NONE = 0x0000;
+ /** set this if it is ok for applications to read user preference files */
+ static const unsigned int USER_READ_OK = 0x0001;
+ /** set this if it is ok for applications to create and write user preference files */
+ static const unsigned int USER_WRITE_OK = 0x0002;
+ /** set this if it is ok for applications to read, create, and write user preference files */
+ static const unsigned int USER_OK = USER_READ_OK | USER_WRITE_OK;
+ /** set this if it is ok for applications to read system wide preference files */
+ static const unsigned int SYSTEM_READ_OK = 0x0004;
+ /** set this if it is ok for applications to create and write system wide preference files */
+ static const unsigned int SYSTEM_WRITE_OK = 0x0008;
+ /** set this if it is ok for applications to read, create, and write system wide preference files */
+ static const unsigned int SYSTEM_OK = SYSTEM_READ_OK | SYSTEM_WRITE_OK;
+ /** set this if it is ok for applications to read, create, and write any kind of preference files */
+ static const unsigned int APP_OK = SYSTEM_OK | USER_OK;
+ /** Set this if it is ok for FLTK to read preference files. USER_READ_OK and/or SYSTEM_READ_OK must also be set. */
+ static const unsigned int CORE_READ_OK = 0x0010;
+ /** Set this if it is ok for FLTK to create or write preference files. USER_WRITE_OK and/or SYSTEM_WRITE_OK must also be set. */
+ static const unsigned int CORE_WRITE_OK = 0x0020;
+ /** set this if it is ok for FLTK to read, create, or write preference files */
+ static const unsigned int CORE_OK = CORE_READ_OK | CORE_WRITE_OK;
+ /** set this to allow FLTK and applications to read preference files */
+ static const unsigned int ALL_READ_OK = USER_READ_OK | SYSTEM_READ_OK | CORE_READ_OK;
+ /** set this to allow FLTK and applications to create and write preference files */
+ static const unsigned int ALL_WRITE_OK = USER_WRITE_OK | SYSTEM_WRITE_OK | CORE_WRITE_OK;
+ /** set this to give FLTK and applications permission to read, write, and create preference files */
+ static const unsigned int ALL = ALL_READ_OK | ALL_WRITE_OK;
+
+ static void file_access(unsigned int flags);
+ static unsigned int file_access();
+
Fl_Preferences( Root root, const char *vendor, const char *application );
Fl_Preferences( const char *path, const char *vendor, const char *application );
Fl_Preferences( Fl_Preferences &parent, const char *group );
@@ -193,6 +232,7 @@ private:
static char nameBuffer[128];
static char uuidBuffer[40];
static Fl_Preferences *runtimePrefs;
+ static unsigned int fileAccess_;
public: // older Sun compilers need this (public definition of the following classes)
class RootNode;
@@ -256,6 +296,7 @@ public: // older Sun compilers need this (public definition of the following cl
Fl_Preferences *prefs_;
char *filename_;
char *vendor_, *application_;
+ Root root_;
public:
RootNode( Fl_Preferences *, Root root, const char *vendor, const char *application );
RootNode( Fl_Preferences *, const char *path, const char *vendor, const char *application );
diff --git a/src/Fl.cxx b/src/Fl.cxx
index 0a4e22ee9..13bd308f1 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -1850,7 +1850,7 @@ bool Fl::option(Fl_Option opt)
if (!options_read_) {
int tmp;
{ // first, read the system wide preferences
- Fl_Preferences prefs(Fl_Preferences::SYSTEM, "fltk.org", "fltk");
+ Fl_Preferences prefs(Fl_Preferences::CORE_SYSTEM, "fltk.org", "fltk");
Fl_Preferences opt_prefs(prefs, "options");
opt_prefs.get("ArrowFocus", tmp, 0); // default: off
options_[OPTION_ARROW_FOCUS] = tmp;
@@ -1874,7 +1874,7 @@ bool Fl::option(Fl_Option opt)
}
{ // next, check the user preferences
// override system options only, if the option is set ( >= 0 )
- Fl_Preferences prefs(Fl_Preferences::USER, "fltk.org", "fltk");
+ Fl_Preferences prefs(Fl_Preferences::CORE_USER, "fltk.org", "fltk");
Fl_Preferences opt_prefs(prefs, "options");
opt_prefs.get("ArrowFocus", tmp, -1);
if (tmp >= 0) options_[OPTION_ARROW_FOCUS] = tmp;
@@ -1896,7 +1896,7 @@ bool Fl::option(Fl_Option opt)
opt_prefs.get("ShowZoomFactor", tmp, -1);
if (tmp >= 0) options_[OPTION_SHOW_SCALING] = tmp;
}
- { // now, if the developer has registered this app, we could as for per-application preferences
+ { // now, if the developer has registered this app, we could ask for per-application preferences
}
options_read_ = 1;
}
diff --git a/src/Fl_File_Chooser.cxx b/src/Fl_File_Chooser.cxx
index 4b0d27f82..43bdc9733 100644
--- a/src/Fl_File_Chooser.cxx
+++ b/src/Fl_File_Chooser.cxx
@@ -168,7 +168,7 @@ void Fl_File_Chooser::cb_favOkButton(Fl_Return_Button* o, void* v) {
Fl_File_Chooser::Fl_File_Chooser(const char *d, const char *p, int t, const char *title) {
if (!prefs_) {
- prefs_ = new Fl_Preferences(Fl_Preferences::USER, "fltk.org", "filechooser");
+ prefs_ = new Fl_Preferences(Fl_Preferences::CORE_USER, "fltk.org", "filechooser");
}
Fl_Group *prev_current = Fl_Group::current();
{ window = new Fl_Double_Window(490, 380, "Choose File");
diff --git a/src/Fl_File_Chooser.fl b/src/Fl_File_Chooser.fl
index fca0a32f3..4cbf3a9fc 100644
--- a/src/Fl_File_Chooser.fl
+++ b/src/Fl_File_Chooser.fl
@@ -70,7 +70,7 @@ class FL_EXPORT Fl_File_Chooser {open
}
Function {Fl_File_Chooser(const char *d, const char *p, int t, const char *title)} {} {
code {if (!prefs_) {
- prefs_ = new Fl_Preferences(Fl_Preferences::USER, "fltk.org", "filechooser");
+ prefs_ = new Fl_Preferences(Fl_Preferences::CORE_USER, "fltk.org", "filechooser");
}} {}
code {Fl_Group *prev_current = Fl_Group::current();} {}
Fl_Window window {
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx
index 48e77bc24..424f0bc87 100644
--- a/src/Fl_Preferences.cxx
+++ b/src/Fl_Preferences.cxx
@@ -32,6 +32,7 @@
char Fl_Preferences::nameBuffer[128];
char Fl_Preferences::uuidBuffer[40];
Fl_Preferences *Fl_Preferences::runtimePrefs = 0;
+unsigned int Fl_Preferences::fileAccess_ = Fl_Preferences::ALL;
/**
Returns a UUID as generated by the system.
@@ -50,6 +51,53 @@ const char *Fl_Preferences::newUUID() {
}
/**
+ Tell the FLTK Preferences system which files in the file system it may read, create, or write.
+
+ The FLTK core library will try to read or even create or write preference files when calling Fl::option(),
+ Fl_File_Chooser, the printing panel, and possibly some other internal function. If your applications wants
+ to keep FLTK from touching the file system, call this function before making any other FLTK calls:
+
+ \code
+ // neiter FLTK nor the app may read, create, or write preference files
+ Fl_Preferences::file_access( Fl_Preferences::NONE );
+ \endcode
+
+ or
+
+ \code
+ // FLTK may not read, create, or write preference files, but the application may
+ Fl_Preferences::file_access( Fl_Preferences::APP_OK );
+ \endcode
+
+ All flags can be combined using an OR operator. If flags are not set, that specifc access to the file system
+ will not be allowed. By default, all access is granted. To clear one or more flags from the default setting, us:
+ \code
+ Fl_Preferences::file_access( Fl_Preferences::file_access()
+ &~ Fl_Preferences::SYSTEM_WRITE );
+ \endcode
+
+ If preferences are created using a filename (instead of Fl_Preferences::USER or Fl_Preferences::SYSTEM),
+ file access is handled as if the Fl_Preferences::USER flag was set.
+
+ \see Fl_Preferences::NONE and others for a list of flags.
+ \see Fl_Preferences::file_access()
+ */
+void Fl_Preferences::file_access(unsigned int flags)
+{
+ fileAccess_ = flags;
+}
+
+/**
+ Return the current file access permissions for the FLTK Preferences system.
+
+ \see Fl_Preferences::file_access(unsigned int)
+ */
+unsigned int Fl_Preferences::file_access()
+{
+ return fileAccess_;
+}
+
+/**
The constructor creates a group that manages name/value pairs and
child groups. Groups are ready for reading and writing at any time.
The root argument is either Fl_Preferences::USER
@@ -807,8 +855,9 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, Root root, const char
: prefs_(prefs),
filename_(0L),
vendor_(0L),
- application_(0L) {
-
+ application_(0L),
+ root_(root)
+{
char *filename = Fl::system_driver()->preference_rootnode(prefs, root, vendor, application);
filename_ = filename ? strdup(filename) : 0L;
vendor_ = strdup(vendor);
@@ -822,7 +871,9 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs, const char *path, con
: prefs_(prefs),
filename_(0L),
vendor_(0L),
- application_(0L) {
+ application_(0L),
+ root_(Fl_Preferences::USER)
+{
if (!vendor)
vendor = "unknown";
@@ -845,7 +896,9 @@ Fl_Preferences::RootNode::RootNode( Fl_Preferences *prefs )
: prefs_(prefs),
filename_(0L),
vendor_(0L),
- application_(0L) {
+ application_(0L),
+ root_(Fl_Preferences::USER)
+{
}
// destroy the root node and all depending nodes
@@ -871,7 +924,19 @@ Fl_Preferences::RootNode::~RootNode() {
// read a preferences file and construct the group tree and with all entry leafs
int Fl_Preferences::RootNode::read() {
if (!filename_) // RUNTIME preferences
- return -1;
+ return -1;
+ if ( (root_ & Fl_Preferences::CORE) && !(fileAccess_ & Fl_Preferences::CORE_READ_OK) ) {
+ prefs_->node->clearDirtyFlags();
+ return -1;
+ }
+ if ( ((root_&Fl_Preferences::ROOT_MASK)==Fl_Preferences::USER) && !(fileAccess_ & Fl_Preferences::USER_READ_OK) ) {
+ prefs_->node->clearDirtyFlags();
+ return -1;
+ }
+ if ( ((root_&Fl_Preferences::ROOT_MASK)==Fl_Preferences::SYSTEM) && !(fileAccess_ & Fl_Preferences::SYSTEM_READ_OK) ) {
+ prefs_->node->clearDirtyFlags();
+ return -1;
+ }
char buf[1024];
FILE *f = fl_fopen( filename_, "rb" );
if ( !f )
@@ -909,6 +974,12 @@ int Fl_Preferences::RootNode::read() {
int Fl_Preferences::RootNode::write() {
if (!filename_) // RUNTIME preferences
return -1;
+ if ( (root_ & Fl_Preferences::CORE) && !(fileAccess_ & Fl_Preferences::CORE_WRITE_OK) )
+ return -1;
+ if ( ((root_&Fl_Preferences::ROOT_MASK)==Fl_Preferences::USER) && !(fileAccess_ & Fl_Preferences::USER_WRITE_OK) )
+ return -1;
+ if ( ((root_&Fl_Preferences::ROOT_MASK)==Fl_Preferences::SYSTEM) && !(fileAccess_ & Fl_Preferences::SYSTEM_WRITE_OK) )
+ return -1;
fl_make_path_for_file(filename_);
FILE *f = fl_fopen( filename_, "wb" );
if ( !f )
diff --git a/src/drivers/Android/Fl_Android_System_Driver.cxx b/src/drivers/Android/Fl_Android_System_Driver.cxx
index 5619be496..0c7185370 100644
--- a/src/drivers/Android/Fl_Android_System_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_System_Driver.cxx
@@ -842,8 +842,8 @@ char *Fl_WinAPI_System_Driver::preference_rootnode(Fl_Preferences *prefs, Fl_Pre
DWORD type, nn;
LONG err;
HKEY key;
-
- switch (root) {
+
+ switch (root&Fl_Preferences::ROOT_MASK) {
case Fl_Preferences::SYSTEM:
err = RegOpenKeyW( HKEY_LOCAL_MACHINE, FLPREFS_RESOURCEW, &key );
if (err == ERROR_SUCCESS) {
diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx
index 0a30de81d..754f29342 100644
--- a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx
+++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx
@@ -249,7 +249,7 @@ char *Fl_Darwin_System_Driver::preference_rootnode(Fl_Preferences *prefs, Fl_Pre
// TODO: verify that this is the Apple sanctioned way of finding these folders
// (On Windows, this frequently leads to issues with internationalized systems)
// Carbon: err = FindFolder( kLocalDomain, kPreferencesFolderType, 1, &spec.vRefNum, &spec.parID );
- switch (root) {
+ switch (root&Fl_Preferences::ROOT_MASK) {
case Fl_Preferences::SYSTEM:
strcpy(filename, "/Library/Preferences");
break;
diff --git a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
index f2b56e0e0..dc7960e62 100644
--- a/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
+++ b/src/drivers/WinAPI/Fl_WinAPI_System_Driver.cxx
@@ -834,7 +834,7 @@ char *Fl_WinAPI_System_Driver::preference_rootnode(Fl_Preferences *prefs, Fl_Pre
LONG err;
HKEY key;
- switch (root) {
+ switch (root&Fl_Preferences::ROOT_MASK) {
case Fl_Preferences::SYSTEM:
err = RegOpenKeyW( HKEY_LOCAL_MACHINE, FLPREFS_RESOURCEW, &key );
if (err == ERROR_SUCCESS) {
diff --git a/src/drivers/X11/Fl_X11_System_Driver.cxx b/src/drivers/X11/Fl_X11_System_Driver.cxx
index 89902b463..b84aba8ea 100644
--- a/src/drivers/X11/Fl_X11_System_Driver.cxx
+++ b/src/drivers/X11/Fl_X11_System_Driver.cxx
@@ -399,7 +399,7 @@ char *Fl_X11_System_Driver::preference_rootnode(Fl_Preferences *prefs, Fl_Prefer
{
static char filename[ FL_PATH_MAX ]; filename[0] = 0;
const char *e;
- switch (root) {
+ switch (root&Fl_Preferences::ROOT_MASK) {
case Fl_Preferences::USER:
if ((e = getenv("HOME")) != NULL) {
strlcpy(filename, e, sizeof(filename));
diff --git a/src/print_panel.cxx b/src/print_panel.cxx
index 4508c9c23..b5fc1d5aa 100644
--- a/src/print_panel.cxx
+++ b/src/print_panel.cxx
@@ -39,7 +39,6 @@
#include <FL/Fl_Preferences.H>
#include <FL/Fl_Int_Input.H>
-static Fl_Preferences print_prefs(Fl_Preferences::USER, "fltk.org", "printers");
static Fl_Double_Window *print_panel=(Fl_Double_Window *)0;
static Fl_Group *print_panel_controls=(Fl_Group *)0;
static Fl_Choice *print_choice=(Fl_Choice *)0;
@@ -225,6 +224,8 @@ static void cb_Save(Fl_Return_Button*, void*) {
int val;
const char *printer = (const char *)print_choice->menu()[print_choice->value()].user_data();
+ Fl_Preferences print_prefs(Fl_Preferences::CORE_USER, "fltk.org", "printers");
+
snprintf(name, sizeof(name), "%s/page_size", printer == NULL ? "" : printer);
print_prefs.set(name, print_page_size->value());
@@ -610,6 +611,8 @@ void print_update_status() {
char name[1024];
int val;
+ Fl_Preferences print_prefs(Fl_Preferences::CORE_USER, "fltk.org", "printers");
+
snprintf(name, sizeof(name), "%s/page_size", printer == NULL ? "" : printer);
print_prefs.get(name, val, 1);
print_page_size->value(val);