From 4c4b67b5bde701e967ed5f46221a7adedc816063 Mon Sep 17 00:00:00 2001 From: Theron Tock Date: Mon, 11 Jul 2011 21:33:13 -0700 Subject: [PATCH] * Implemented #2514, support for address table alternate paths. There's a "data directory" setting under user preferences. If the user selects an address table file using "choose file" and that file is "inside" the data directory, then the appropriate part of the path is replaced with %DATADIR% as a variable. If the address table is marked "run-time" then the path is taken from the firewall data directory option. --- doc/ChangeLog | 9 +++ src/compiler_lib/CompilerDriver.cpp | 6 ++ src/gui/main.cpp | 1 + src/ipt/ipt.cpp | 2 +- src/iptlib/NATCompiler_ipt.cpp | 17 ++++- src/iptlib/PolicyCompiler_ipt.cpp | 17 ++++- src/iptlib/Preprocessor_ipt.cpp | 2 +- .../src/fwbuilder/AddressTable.cpp | 37 +++++++-- src/libfwbuilder/src/fwbuilder/AddressTable.h | 6 +- .../src/fwbuilder/AttachedNetworks.cpp | 3 +- .../src/fwbuilder/AttachedNetworks.h | 3 +- src/libfwbuilder/src/fwbuilder/DNSName.cpp | 3 +- src/libfwbuilder/src/fwbuilder/DNSName.h | 3 +- .../src/fwbuilder/DynamicGroup.cpp | 2 +- src/libfwbuilder/src/fwbuilder/DynamicGroup.h | 4 +- src/libfwbuilder/src/fwbuilder/FWObject.cpp | 1 + src/libfwbuilder/src/fwbuilder/FWObject.h | 5 ++ .../src/fwbuilder/MultiAddress.cpp | 19 +++-- src/libfwbuilder/src/fwbuilder/MultiAddress.h | 5 +- .../src/fwcompiler/Preprocessor.cpp | 2 +- src/libgui/AddressTableDialog.cpp | 62 +++++++++++++++ src/libgui/FWBSettings.cpp | 19 ++++- src/libgui/FWBSettings.h | 8 +- src/libgui/PrefsDialog.cpp | 41 ++++++++-- src/libgui/PrefsDialog.h | 1 + src/libgui/freebsdAdvancedDialog.cpp | 3 + src/libgui/freebsdadvanceddialog_q.ui | 74 +++++++++++++++++- src/libgui/linux24AdvancedDialog.cpp | 2 + src/libgui/linux24advanceddialog_q.ui | 76 ++++++++++++++++++- src/libgui/openbsdAdvancedDialog.cpp | 3 + src/libgui/openbsdadvanceddialog_q.ui | 74 +++++++++++++++++- src/libgui/prefsdialog_q.ui | 59 +++++++++++++- src/pf/pf.cpp | 2 +- src/pflib/CompilerDriver_pf_run.cpp | 5 +- src/pflib/TableFactory.cpp | 16 +++- src/pflib/TableFactory.h | 4 +- 36 files changed, 544 insertions(+), 52 deletions(-) diff --git a/doc/ChangeLog b/doc/ChangeLog index 5e6792496..ea8cb92a2 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,3 +1,12 @@ +2011-07-11 theron + * Implemented #2514, support for address table alternate paths. + There's a "data directory" setting under user preferences. If the + user selects an address table file using "choose file" and that + file is "inside" the data directory, then the appropriate part of + the path is replaced with %DATADIR% as a variable. If the address + table is marked "run-time" then the path is taken from the + firewall data directory option. + 2011-07-09 vadim * pf.g (rule_extended): see #2551 Importer should parse PF rules diff --git a/src/compiler_lib/CompilerDriver.cpp b/src/compiler_lib/CompilerDriver.cpp index 74b29b469..0e8817735 100644 --- a/src/compiler_lib/CompilerDriver.cpp +++ b/src/compiler_lib/CompilerDriver.cpp @@ -187,6 +187,12 @@ bool CompilerDriver::configure(const QStringList &args) wdir = string(args.at(idx).toLatin1().constData()); continue; } + if (arg == "-D") + { + idx++; + FWObject::setDataDir(args.at(idx).toUtf8().constData()); + continue; + } if (arg == "-f") { idx++; diff --git a/src/gui/main.cpp b/src/gui/main.cpp index d94d9a4e0..3052a238e 100644 --- a/src/gui/main.cpp +++ b/src/gui/main.cpp @@ -182,6 +182,7 @@ int main( int argc, char *argv[] ) if (fwbdebug) qDebug("Reading settings ..."); st = new FWBSettings(); st->init(force_first_time_run_flag); + FWObject::setDataDir(st->getDataDir().toUtf8().constData()); if (fwbdebug) qDebug("done"); wfl = new UserWorkflow(); diff --git a/src/ipt/ipt.cpp b/src/ipt/ipt.cpp index 4deb0c1d3..f3fe8e310 100644 --- a/src/ipt/ipt.cpp +++ b/src/ipt/ipt.cpp @@ -71,7 +71,7 @@ void usage(const char *name) cout << "Version " << VERSION << endl; cout << "Usage: " << name << " [-x level] [-v] [-V] [-q] [-f filename.xml] [-d destdir] " - "[-m] [-4|-6] firewall_object_name" << endl; + "[-D datadir ] [-m] [-4|-6] firewall_object_name" << endl; } int main(int argc, char **argv) diff --git a/src/iptlib/NATCompiler_ipt.cpp b/src/iptlib/NATCompiler_ipt.cpp index 04a73a331..b878c79b0 100644 --- a/src/iptlib/NATCompiler_ipt.cpp +++ b/src/iptlib/NATCompiler_ipt.cpp @@ -2316,7 +2316,13 @@ bool NATCompiler_ipt::processMultiAddressObjectsInRE::processNext() // we have just one object in RE and this object is MutiAddressRunTime if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { - rule->setStr("address_table_file",atrt->getSourceName()); + string path = + atrt->getSourceNameAsPath(compiler->getCachedFwOpt()); + if (path.empty()) { + compiler->abort(rule, "Empty path or data directory for address table: " + atrt->getName()); + return true; + } + rule->setStr("address_table_file", path); osconf->registerMultiAddressObject(atrt); } if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) @@ -2353,7 +2359,14 @@ bool NATCompiler_ipt::processMultiAddressObjectsInRE::processNext() nre=RuleElement::cast( r->getFirstByType(re_type) ); nre->clearChildren(); nre->addRef( atrt ); - r->setStr("address_table_file",atrt->getSourceName()); + + string path = atrt->getSourceNameAsPath(compiler->getCachedFwOpt()); + if (path.empty()) { + compiler->abort(rule, "Empty path or data directory for address table: " + atrt->getName()); + return true; + } + r->setStr("address_table_file", path); + osconf->registerMultiAddressObject(atrt); tmp_queue.push_back(r); diff --git a/src/iptlib/PolicyCompiler_ipt.cpp b/src/iptlib/PolicyCompiler_ipt.cpp index b9ea48a6f..888ab6bb4 100644 --- a/src/iptlib/PolicyCompiler_ipt.cpp +++ b/src/iptlib/PolicyCompiler_ipt.cpp @@ -3894,7 +3894,13 @@ bool PolicyCompiler_ipt::processMultiAddressObjectsInRE::processNext() // we have just one object in RE and this object is MutiAddressRunTime if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME) { - rule->setStr("address_table_file",atrt->getSourceName()); + string path = + atrt->getSourceNameAsPath(compiler->getCachedFwOpt()); + if (path.empty()) { + compiler->abort(rule, "Empty path or data directory for address table: " + atrt->getName()); + return true; + } + rule->setStr("address_table_file", path); osconf->registerMultiAddressObject(atrt); } if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME) @@ -3935,7 +3941,14 @@ bool PolicyCompiler_ipt::processMultiAddressObjectsInRE::processNext() nre=RuleElement::cast( r->getFirstByType(re_type) ); nre->clearChildren(); nre->addRef( atrt ); - r->setStr("address_table_file",atrt->getSourceName()); + + string path = atrt->getSourceNameAsPath(compiler->getCachedFwOpt()); + if (path.empty()) { + compiler->abort(rule, "Empty path or data directory for address table: " + atrt->getName()); + return true; + } + r->setStr("address_table_file", path); + osconf->registerMultiAddressObject(atrt); tmp_queue.push_back(r); diff --git a/src/iptlib/Preprocessor_ipt.cpp b/src/iptlib/Preprocessor_ipt.cpp index 09135be7f..ab6bb74b7 100644 --- a/src/iptlib/Preprocessor_ipt.cpp +++ b/src/iptlib/Preprocessor_ipt.cpp @@ -42,7 +42,7 @@ void Preprocessor_ipt::convertObject(FWObject *obj) if (intf->isRegular()) { att->setCompileTime(true); - att->loadFromSource(ipv6, inTestMode()); + att->loadFromSource(ipv6, getCachedFwOpt(), inTestMode()); } else att->setRunTime(true); } else Preprocessor::convertObject(obj); diff --git a/src/libfwbuilder/src/fwbuilder/AddressTable.cpp b/src/libfwbuilder/src/fwbuilder/AddressTable.cpp index 900a58ae2..084161fad 100644 --- a/src/libfwbuilder/src/fwbuilder/AddressTable.cpp +++ b/src/libfwbuilder/src/fwbuilder/AddressTable.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -88,6 +89,30 @@ xmlNodePtr AddressTable::toXML(xmlNodePtr parent) throw(FWException) return me; } + +string AddressTable::getFilename(FWOptions *options) throw (FWException) +{ + string path = getStr("filename"); + size_t found = path.find("%DATADIR%"); + if (found == string::npos) return path; + + string dataDir; + if (isRunTime()) { + dataDir = options->getStr("data_dir"); + if (dataDir.empty()) { + throw FWException("Firewall 'data directory' setting is blank"); + } + } else { + dataDir = FWObject::getDataDir(); + if (dataDir.empty()) { + throw FWException("Global 'data directory' setting is blank"); + } + } + + path.replace(found, 9, dataDir); + return path; +} + /* * read file specified by the "filename" attribute and interpret lines * as addresses. Create corresponding address or network objects, add @@ -99,9 +124,11 @@ xmlNodePtr AddressTable::toXML(xmlNodePtr parent) throw(FWException) * TODO: new objects should be added to some kind of special group in * the object tree, something with the name "tmp" or similar. */ -void AddressTable::loadFromSource(bool ipv6, bool test_mode) throw(FWException) +void AddressTable::loadFromSource(bool ipv6, FWOptions *options, + bool test_mode) throw(FWException) { - ifstream fs(getStr("filename").c_str()); + string path = getFilename(options); + ifstream fs(path.c_str()); ostringstream exmess; string buf; size_type pos; @@ -142,7 +169,7 @@ void AddressTable::loadFromSource(bool ipv6, bool test_mode) throw(FWException) } catch (FWException &ex) { exmess << "Invalid address: " - << getStr("filename") << ":" + << path << ":" << line << " \"" << buf << "\""; throw FWException(exmess.str()); @@ -161,7 +188,7 @@ void AddressTable::loadFromSource(bool ipv6, bool test_mode) throw(FWException) } catch (FWException &ex) { exmess << "Invalid address: " - << getStr("filename") << ":" + << path << ":" << line << " \"" << buf << "\""; throw FWException(exmess.str()); @@ -188,7 +215,7 @@ void AddressTable::loadFromSource(bool ipv6, bool test_mode) throw(FWException) // Compiler should print error message but continue. exmess << "File not found for Address Table: " << getName() - << " (" << getStr("filename") << ")"; + << " (" << path << ")"; if (test_mode) { exmess << " Using dummy address in test mode"; diff --git a/src/libfwbuilder/src/fwbuilder/AddressTable.h b/src/libfwbuilder/src/fwbuilder/AddressTable.h index 9c2a79099..34c749d30 100644 --- a/src/libfwbuilder/src/fwbuilder/AddressTable.h +++ b/src/libfwbuilder/src/fwbuilder/AddressTable.h @@ -35,7 +35,8 @@ namespace libfwbuilder class AddressTable : public MultiAddress { private: - + + std::string getFilename(FWOptions *options) throw(FWException); public: @@ -50,7 +51,8 @@ class AddressTable : public MultiAddress virtual std::string getSourceName(); virtual void setSourceName(const std::string& source_name); - virtual void loadFromSource(bool ipv6, bool test_mode=false) throw(FWException); + virtual void loadFromSource(bool ipv6, FWOptions *options, + bool test_mode=false) throw(FWException); }; } diff --git a/src/libfwbuilder/src/fwbuilder/AttachedNetworks.cpp b/src/libfwbuilder/src/fwbuilder/AttachedNetworks.cpp index c54b478c6..1d4ed19e3 100644 --- a/src/libfwbuilder/src/fwbuilder/AttachedNetworks.cpp +++ b/src/libfwbuilder/src/fwbuilder/AttachedNetworks.cpp @@ -108,7 +108,8 @@ void AttachedNetworks::addNetworkObject(const InetAddr *ip_addr, * Read addresses of the parent interface and build a group of * corresponding networks. */ -void AttachedNetworks::loadFromSource(bool ipv6, bool ) throw(FWException) +void AttachedNetworks::loadFromSource(bool ipv6, FWOptions *options, + bool inTestMode) throw(FWException) { Interface *parent_intf = Interface::cast(getParent()); assert(parent_intf); diff --git a/src/libfwbuilder/src/fwbuilder/AttachedNetworks.h b/src/libfwbuilder/src/fwbuilder/AttachedNetworks.h index 0c1c6c2c0..fabf95fe3 100644 --- a/src/libfwbuilder/src/fwbuilder/AttachedNetworks.h +++ b/src/libfwbuilder/src/fwbuilder/AttachedNetworks.h @@ -46,7 +46,8 @@ class AttachedNetworks : public MultiAddress virtual void fromXML(xmlNodePtr parent) throw(FWException); virtual xmlNodePtr toXML(xmlNodePtr xml_parent_node) throw(FWException); - virtual void loadFromSource(bool ipv6, bool test_mode=false) throw(FWException); + virtual void loadFromSource(bool ipv6, FWOptions *options, + bool test_mode=false) throw(FWException); virtual std::string getSourceName(); }; diff --git a/src/libfwbuilder/src/fwbuilder/DNSName.cpp b/src/libfwbuilder/src/fwbuilder/DNSName.cpp index aa833bf78..a428840cd 100644 --- a/src/libfwbuilder/src/fwbuilder/DNSName.cpp +++ b/src/libfwbuilder/src/fwbuilder/DNSName.cpp @@ -118,7 +118,8 @@ xmlNodePtr DNSName::toXML(xmlNodePtr parent) throw(FWException) * TODO: new object should be added to some kind of special group in * the object tree, something with the name "tmp" or similar. */ -void DNSName::loadFromSource(bool ipv6, bool test_mode) throw(FWException) +void DNSName::loadFromSource(bool ipv6, FWOptions *options, + bool test_mode) throw(FWException) { int af_type = (ipv6)?AF_INET6:AF_INET; try diff --git a/src/libfwbuilder/src/fwbuilder/DNSName.h b/src/libfwbuilder/src/fwbuilder/DNSName.h index d725bfd4c..640761a03 100644 --- a/src/libfwbuilder/src/fwbuilder/DNSName.h +++ b/src/libfwbuilder/src/fwbuilder/DNSName.h @@ -54,7 +54,8 @@ class DNSName : public MultiAddress std::string getDNSRecordType(); void setDNSRecordType(const std::string& rectype); - virtual void loadFromSource(bool ipv6, bool test_mode=false) throw(FWException); + virtual void loadFromSource(bool ipv6, FWOptions *options, + bool test_mode=false) throw(FWException); }; } diff --git a/src/libfwbuilder/src/fwbuilder/DynamicGroup.cpp b/src/libfwbuilder/src/fwbuilder/DynamicGroup.cpp index ac8e1c9d6..815c0cde7 100644 --- a/src/libfwbuilder/src/fwbuilder/DynamicGroup.cpp +++ b/src/libfwbuilder/src/fwbuilder/DynamicGroup.cpp @@ -142,7 +142,7 @@ bool DynamicGroup::isCompileTime() const } -void DynamicGroup::loadFromSource(bool ipv6, bool test_mode) +void DynamicGroup::loadFromSource(bool ipv6, FWOptions *options, bool test_mode) throw (FWException) { FWObjectDatabase *root = getRoot(); diff --git a/src/libfwbuilder/src/fwbuilder/DynamicGroup.h b/src/libfwbuilder/src/fwbuilder/DynamicGroup.h index 948479908..459427072 100644 --- a/src/libfwbuilder/src/fwbuilder/DynamicGroup.h +++ b/src/libfwbuilder/src/fwbuilder/DynamicGroup.h @@ -58,8 +58,8 @@ class DynamicGroup : public MultiAddress throw (FWException); virtual bool isCompileTime() const; - virtual void loadFromSource(bool ipv6, bool test_mode=false) - throw (FWException); + virtual void loadFromSource(bool ipv6, FWOptions *options, + bool test_mode=false) throw (FWException); /* * verify whether given object type is approppriate as a child diff --git a/src/libfwbuilder/src/fwbuilder/FWObject.cpp b/src/libfwbuilder/src/fwbuilder/FWObject.cpp index 4a4101b21..041e222fb 100644 --- a/src/libfwbuilder/src/fwbuilder/FWObject.cpp +++ b/src/libfwbuilder/src/fwbuilder/FWObject.cpp @@ -58,6 +58,7 @@ using namespace libfwbuilder; const char *FWObject::TYPENAME={"UNDEF"}; string FWObject::NOT_FOUND=""; +string FWObject::dataDir; //#define FWB_DEBUG diff --git a/src/libfwbuilder/src/fwbuilder/FWObject.h b/src/libfwbuilder/src/fwbuilder/FWObject.h index d6932d3c1..8a3afe763 100644 --- a/src/libfwbuilder/src/fwbuilder/FWObject.h +++ b/src/libfwbuilder/src/fwbuilder/FWObject.h @@ -121,6 +121,8 @@ private: time_t creation_time; std::set keywords; + static std::string dataDir; + protected: std::string xml_name; @@ -571,6 +573,9 @@ public: void addKeyword(const std::string &keyword); void removeKeyword(const std::string &keyword); void clearKeywords(); + + static std::string getDataDir() { return dataDir; } + static void setDataDir(const std::string &dir) { dataDir = dir; } }; class FWObjectTypedChildIterator diff --git a/src/libfwbuilder/src/fwbuilder/MultiAddress.cpp b/src/libfwbuilder/src/fwbuilder/MultiAddress.cpp index 17a266491..5ae634d07 100644 --- a/src/libfwbuilder/src/fwbuilder/MultiAddress.cpp +++ b/src/libfwbuilder/src/fwbuilder/MultiAddress.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -86,12 +87,6 @@ bool MultiAddress::validateChild(FWObject *o) return ObjectGroup::validateChild(o); } -void MultiAddress::loadFromSource(bool, bool) throw(FWException) -{ - cerr << "virtual function MultiAddress::loadFromSource is not implemented" - << endl; -} - // ======================================================================== const char *MultiAddressRunTime::TYPENAME={"MultiAddressRunTime"}; @@ -112,3 +107,15 @@ MultiAddressRunTime::MultiAddressRunTime(MultiAddress *maddr) subst_type_name = maddr->getTypeName(); } +string MultiAddressRunTime::getSourceNameAsPath(FWOptions *options) const +{ + string ret = source_name; + size_t found = ret.find("%DATADIR%"); + if (found == string::npos) return ret; + + string dataDir = options->getStr("data_dir"); + if (dataDir.empty()) return dataDir; + + ret.replace(found, 9, dataDir); + return ret; +} diff --git a/src/libfwbuilder/src/fwbuilder/MultiAddress.h b/src/libfwbuilder/src/fwbuilder/MultiAddress.h index a57affaf4..574bd99d2 100644 --- a/src/libfwbuilder/src/fwbuilder/MultiAddress.h +++ b/src/libfwbuilder/src/fwbuilder/MultiAddress.h @@ -52,7 +52,8 @@ class MultiAddress : public ObjectGroup virtual std::string getSourceName(); virtual void setSourceName(const std::string& source_name); - virtual void loadFromSource(bool ipv6, bool test_mode=false) throw(FWException); + virtual void loadFromSource(bool ipv6, FWOptions *options, + bool test_mode=false) throw(FWException) = 0; /* * functions isCompileTime() and isRunTime() are virtual because @@ -101,6 +102,8 @@ public: std::string getSourceName() const { return source_name; } std::string getSubstitutionTypeName() const { return subst_type_name; } + std::string getSourceNameAsPath(FWOptions *options) const; + bool isCompileTime() const { return !run_time; } bool isRunTime() const { return run_time; } diff --git a/src/libfwbuilder/src/fwcompiler/Preprocessor.cpp b/src/libfwbuilder/src/fwcompiler/Preprocessor.cpp index 77b008e9f..345f5837b 100644 --- a/src/libfwbuilder/src/fwcompiler/Preprocessor.cpp +++ b/src/libfwbuilder/src/fwcompiler/Preprocessor.cpp @@ -73,7 +73,7 @@ void Preprocessor::convertObject(FWObject *obj) MultiAddress *adt = MultiAddress::cast(obj); if (adt!=NULL && adt->isCompileTime()) { - adt->loadFromSource(ipv6, inTestMode()); + adt->loadFromSource(ipv6, getCachedFwOpt(), inTestMode()); } } diff --git a/src/libgui/AddressTableDialog.cpp b/src/libgui/AddressTableDialog.cpp index 050d15547..7c9f2c02e 100644 --- a/src/libgui/AddressTableDialog.cpp +++ b/src/libgui/AddressTableDialog.cpp @@ -148,6 +148,42 @@ void AddressTableDialog::applyChanges() } + +static void doReminderAboutDataDir() +{ + if (st->isReminderAboutDataDirSuppressed()) return; + + QMessageBox msgBox; + msgBox.setText("The file you selected is inside the " + "'data directory' global preference. The path of the " + "file has been converted to use the variable %DATADIR% " + "so that expansion will happen properly within rules."); + + msgBox.setWindowModality(Qt::ApplicationModal); + msgBox.setWindowFlags(Qt::Window | + Qt::WindowTitleHint | + Qt::CustomizeWindowHint | + Qt::WindowCloseButtonHint | + Qt::WindowSystemMenuHint); + + msgBox.setWindowTitle("Data directory conversion"); + + QCheckBox cb("Do not show this again", &msgBox); + msgBox.addButton(&cb, QMessageBox::ResetRole); + msgBox.addButton(QMessageBox::Close); + msgBox.setDefaultButton(QMessageBox::Close); + msgBox.setIcon(QMessageBox::Information); + + /* Hack alert! Disconnect signals from the checkbox so that + QMessageBox doesn't know when it gets clicked, and treat it + like an "OK" action. */ + cb.disconnect(); + + msgBox.exec(); + if (cb.isChecked()) st->suppressReminderAboutDataDir(true); +} + + void AddressTableDialog::browse() { // build a dialog that will let user select existing file or enter @@ -162,6 +198,21 @@ void AddressTableDialog::browse() if (s.isEmpty()) return; st->setOpenFileDir(s); + QString dataDir = st->getDataDir(); + if (!dataDir.isEmpty()) { + QString dataDirPath = QFileInfo(dataDir).canonicalFilePath(); + QString filePath = QFileInfo(s).canonicalFilePath(); + if (filePath.length() > 0 && filePath.startsWith(dataDirPath)) { + int truncateLen = dataDirPath.length(); + if (dataDirPath.at(truncateLen-1) == '/' || + dataDirPath.at(truncateLen-1) == '\\') { + truncateLen--; + } + s = filePath.replace(0, truncateLen, "%DATADIR%"); + doReminderAboutDataDir(); + } + } + m_dialog->filename->setText(s); // assign focus to the "file name" input field so that it // generates signal editFinished when user clicks @@ -174,6 +225,17 @@ void AddressTableDialog::browse() void AddressTableDialog::editFile( void ) { QString filePath = m_dialog->filename->text(); + if (filePath.startsWith("%DATADIR%")) { + QString dataDir = st->getDataDir(); + if (dataDir.isEmpty()) { + QMessageBox::critical(this, "Firewall Builder", + tr("Data directory setting is blank " + "and path contains %DATADIR% variable")); + return; + } + filePath.replace(0, 9, dataDir); + } + TextFileEditor editor(this, filePath); if (editor.load()) editor.exec(); // its modal dialog diff --git a/src/libgui/FWBSettings.cpp b/src/libgui/FWBSettings.cpp index 8c590056b..b8679f35d 100644 --- a/src/libgui/FWBSettings.cpp +++ b/src/libgui/FWBSettings.cpp @@ -69,6 +69,7 @@ const char* DTDSetpath = SETTINGS_PATH_PREFIX "/System/DTDPath"; const char* ResSetpath = SETTINGS_PATH_PREFIX "/System/ResPath"; const char* compression = SETTINGS_PATH_PREFIX "/DataFile/compression"; const char* wdirSetpath = SETTINGS_PATH_PREFIX "/Environment/WDir"; +const char* datadirSetpath = SETTINGS_PATH_PREFIX "/Environment/DataDir"; const char* ofdirSetpath = SETTINGS_PATH_PREFIX "/Environment/OpenFileDir"; const char* startupActionSetpath = SETTINGS_PATH_PREFIX "/Environment/StartupAction"; @@ -114,6 +115,7 @@ const char* announcementLastTime = const char* checkUpdatesProxy = SETTINGS_PATH_PREFIX "/UI/CheckUpdatesProxy"; const char* reminderAboutStandardLibSuppressed = SETTINGS_PATH_PREFIX "/UI/reminderAboutStandardLibSuppressed"; +const char* reminderDataDir = SETTINGS_PATH_PREFIX "/UI/reminderDataDir"; const char* introDialogEnabled = SETTINGS_PATH_PREFIX "/UI/introDialogEnabled"; const char* newFirewallPlatform = SETTINGS_PATH_PREFIX "/Objects/NewFireallPlatform"; @@ -413,6 +415,16 @@ void FWBSettings::suppressReminderAboutStandardLib(bool f) setValue(reminderAboutStandardLibSuppressed, f); } +bool FWBSettings::isReminderAboutDataDirSuppressed() +{ + return value(reminderDataDir).toBool(); +} + +void FWBSettings::suppressReminderAboutDataDir(bool f) +{ + setValue(reminderDataDir, f); +} + bool FWBSettings::hasKey(const QString &attribute) { return QSettings::contains(SETTINGS_PATH_PREFIX "/" + attribute); @@ -473,7 +485,12 @@ void FWBSettings::setList(const QString &attribute, QStringList &list) } QString FWBSettings::getWDir() { return value(wdirSetpath).toString();} -void FWBSettings::setWDir( const QString &wd ) { setValue(wdirSetpath,wd);} +void FWBSettings::setWDir(const QString &wd) { setValue(wdirSetpath, wd);} +QString FWBSettings::getDataDir() { return value(datadirSetpath).toString();} +void FWBSettings::setDataDir(const QString &d) { + setValue(datadirSetpath, d); + FWObject::setDataDir(d.toUtf8().constData()); +} int FWBSettings::getInfoStyle() { return value(infoStyleSetpath).toInt();} void FWBSettings::setInfoStyle(int s) { setValue(infoStyleSetpath,s);} int FWBSettings::getInfoWindowHeight() { return value(infoWindowHSetpath).toInt();} diff --git a/src/libgui/FWBSettings.h b/src/libgui/FWBSettings.h index c1ffed698..5e8b57745 100644 --- a/src/libgui/FWBSettings.h +++ b/src/libgui/FWBSettings.h @@ -81,7 +81,10 @@ class FWBSettings : public QSettings bool isFirstRun() { return first_run; } QString getWDir(); - void setWDir( const QString &wd ); + void setWDir(const QString &wd); + + QString getDataDir(); + void setDataDir(const QString &dataDir); QString getOpenFileDir( const QString &existingPath = ""); void setOpenFileDir( const QString &d ); @@ -180,6 +183,9 @@ class FWBSettings : public QSettings bool isReminderAboutStandardLibSuppressed(); void suppressReminderAboutStandardLib(bool f); + bool isReminderAboutDataDirSuppressed(); + void suppressReminderAboutDataDir(bool f); + enum IconSize getIconsInRulesSize(); void setIconsInRulesSize(enum IconSize size); diff --git a/src/libgui/PrefsDialog.cpp b/src/libgui/PrefsDialog.cpp index 713fda5ba..e6e8ea6a5 100644 --- a/src/libgui/PrefsDialog.cpp +++ b/src/libgui/PrefsDialog.cpp @@ -112,7 +112,8 @@ PrefsDialog::PrefsDialog(QWidget *parent) : QDialog(parent) m_dialog->tabWidget->setCurrentIndex(0); - m_dialog->wDir->setText( st->getWDir() ); + m_dialog->wDir->setText(st->getWDir()); + m_dialog->dataDir->setText(st->getDataDir()); m_dialog->objTooltips->setChecked( st->getObjTooltips() ); m_dialog->advTooltipMode->setChecked(st->getBool("UI/AdvancedTooltips")); @@ -388,17 +389,40 @@ void PrefsDialog::changeFont(QFont &font) void PrefsDialog::findWDir() { - QString wd = st->getWDir(); + QString wd = m_dialog->wDir->text(); + if (wd.isEmpty()) wd = st->getWDir(); + if (wd.isEmpty()) wd = st->getOpenFileDir(); QString dir = QFileDialog::getExistingDirectory( - this, tr("Find working directory"), wd, QFileDialog::ShowDirsOnly ); + this, tr("Find working directory"), wd, QFileDialog::ShowDirsOnly); - if (!dir.isEmpty()) m_dialog->wDir->setText(dir); + if (dir.isEmpty()) return; + st->setOpenFileDir(dir); + + m_dialog->wDir->setText(dir); +} + +void PrefsDialog::findDataDir() +{ + QString dataDir = m_dialog->dataDir->text(); + if (dataDir.isEmpty()) dataDir = st->getDataDir(); + if (dataDir.isEmpty()) dataDir = st->getOpenFileDir(); + QString dir = QFileDialog::getExistingDirectory( + this, tr("Find data directory"), dataDir, QFileDialog::ShowDirsOnly); + + if (dir.isEmpty()) return; + st->setOpenFileDir(dir); + + m_dialog->dataDir->setText(dir); } void PrefsDialog::findSSH() { + QString sshPath = m_dialog->sshPath->text(); + if (!QFileInfo(sshPath).isFile()) sshPath = st->getSSHPath(); + if (!QFileInfo(sshPath).isFile()) sshPath = st->getOpenFileDir(); + QString fp = QFileDialog::getOpenFileName( - this, tr("Find Secure Shell utility"), st->getOpenFileDir()); + this, tr("Find Secure Shell utility"), sshPath); if (fp.isEmpty()) return; st->setOpenFileDir(fp); @@ -408,8 +432,12 @@ void PrefsDialog::findSSH() void PrefsDialog::findSCP() { + QString scpPath = m_dialog->scpPath->text(); + if (!QFileInfo(scpPath).isFile()) scpPath = st->getSCPPath(); + if (!QFileInfo(scpPath).isFile()) scpPath = st->getOpenFileDir(); + QString fp = QFileDialog::getOpenFileName( - this, tr("Find SCP utility"), st->getOpenFileDir()); + this, tr("Find SCP utility"), scpPath); if (fp.isEmpty()) return; st->setOpenFileDir(fp); @@ -424,6 +452,7 @@ void PrefsDialog::accept() /* check if the default working directory does not exist yet */ st->setWDir( wd ); + st->setDataDir(m_dialog->dataDir->text()); st->setObjTooltips( m_dialog->objTooltips->isChecked() ); st->setBool("UI/AdvancedTooltips", m_dialog->advTooltipMode->isChecked()); diff --git a/src/libgui/PrefsDialog.h b/src/libgui/PrefsDialog.h index 6c8c20722..311e59cf0 100644 --- a/src/libgui/PrefsDialog.h +++ b/src/libgui/PrefsDialog.h @@ -70,6 +70,7 @@ public: public slots: virtual void accept(); virtual void findWDir(); + virtual void findDataDir(); virtual void findSSH(); virtual void findSCP(); virtual void changeRedColor(); diff --git a/src/libgui/freebsdAdvancedDialog.cpp b/src/libgui/freebsdAdvancedDialog.cpp index b0f798211..0268a1b5b 100644 --- a/src/libgui/freebsdAdvancedDialog.cpp +++ b/src/libgui/freebsdAdvancedDialog.cpp @@ -99,6 +99,9 @@ freebsdAdvancedDialog::freebsdAdvancedDialog(QWidget *parent,FWObject *o) data.registerOption(m_dialog->freebsd_path_pfctl, fwopt, "freebsd_path_pfctl"); + data.registerOption(m_dialog->freebsd_data_dir, + fwopt, "data_dir"); + data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); diff --git a/src/libgui/freebsdadvanceddialog_q.ui b/src/libgui/freebsdadvanceddialog_q.ui index 843570a40..a558a7a92 100644 --- a/src/libgui/freebsdadvanceddialog_q.ui +++ b/src/libgui/freebsdadvanceddialog_q.ui @@ -23,7 +23,7 @@ QTabWidget::Rounded - 0 + 2 @@ -406,6 +406,78 @@ + + + Data + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Specify directory where data files (e.g. run-time address table) are found on the firewall. + + + Qt::AlignCenter + + + true + + + + + + + Data directory: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + + + + + + 300 + 0 + + + + + + + + Qt::Vertical + + + + 20 + 155 + + + + + + diff --git a/src/libgui/linux24AdvancedDialog.cpp b/src/libgui/linux24AdvancedDialog.cpp index c2773ba6b..012da8f07 100644 --- a/src/libgui/linux24AdvancedDialog.cpp +++ b/src/libgui/linux24AdvancedDialog.cpp @@ -188,6 +188,8 @@ linux24AdvancedDialog::linux24AdvancedDialog(QWidget *parent,FWObject *o) fwopt, "linux24_conntrack_tcp_be_liberal", threeStateMapping); + data.registerOption(m_dialog->linux24_data_dir, fwopt, "data_dir"); + data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); diff --git a/src/libgui/linux24advanceddialog_q.ui b/src/libgui/linux24advanceddialog_q.ui index 95f57e466..0f7235a9c 100644 --- a/src/libgui/linux24advanceddialog_q.ui +++ b/src/libgui/linux24advanceddialog_q.ui @@ -10,7 +10,7 @@ 0 0 493 - 531 + 566 @@ -23,7 +23,7 @@ QTabWidget::Rounded - 0 + 4 @@ -1209,6 +1209,78 @@ Explanation of this parameter can be found at<br> + + + Data + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Specify directory where data files (e.g. run-time address table) are found on the firewall. + + + Qt::AlignCenter + + + true + + + + + + + Data directory: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + + + + + + 300 + 0 + + + + + + + + Qt::Vertical + + + + 20 + 358 + + + + + + diff --git a/src/libgui/openbsdAdvancedDialog.cpp b/src/libgui/openbsdAdvancedDialog.cpp index 783f2d31f..c5d67023f 100644 --- a/src/libgui/openbsdAdvancedDialog.cpp +++ b/src/libgui/openbsdAdvancedDialog.cpp @@ -99,6 +99,9 @@ openbsdAdvancedDialog::openbsdAdvancedDialog(QWidget *parent,FWObject *o) data.registerOption( m_dialog->openbsd_path_sysctl, fwopt, "openbsd_path_sysctl"); + + data.registerOption(m_dialog->openbsd_data_dir, fwopt, "data_dir"); + data.loadAll(); m_dialog->tabWidget->setCurrentIndex(0); diff --git a/src/libgui/openbsdadvanceddialog_q.ui b/src/libgui/openbsdadvanceddialog_q.ui index 8fe9def71..c1bf74299 100644 --- a/src/libgui/openbsdadvanceddialog_q.ui +++ b/src/libgui/openbsdadvanceddialog_q.ui @@ -23,7 +23,7 @@ - 0 + 2 @@ -379,6 +379,78 @@ + + + Data + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + Specify directory where data files (e.g. run-time address table) are found on the firewall. + + + Qt::AlignCenter + + + true + + + + + + + Data directory: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + false + + + + + + + + 200 + 0 + + + + + + + + Qt::Vertical + + + + 20 + 118 + + + + + + diff --git a/src/libgui/prefsdialog_q.ui b/src/libgui/prefsdialog_q.ui index 16ef6a42a..7dfbfcd3c 100644 --- a/src/libgui/prefsdialog_q.ui +++ b/src/libgui/prefsdialog_q.ui @@ -83,8 +83,8 @@ 20 - - + + @@ -100,7 +100,7 @@ - + @@ -110,7 +110,7 @@ - + @@ -129,6 +129,51 @@ + + + + + 0 + 0 + + + + Data directory: + + + false + + + + + + + + 0 + 0 + + + + + + + + + 0 + 0 + + + + + 200 + 16777215 + + + + Browse... + + + @@ -1688,6 +1733,12 @@ are never stored permanently) + + browseDataDir + clicked() + prefsDialog_q + findDataDir() + redBtn clicked() diff --git a/src/pf/pf.cpp b/src/pf/pf.cpp index d0d409bd0..5f19f14f8 100644 --- a/src/pf/pf.cpp +++ b/src/pf/pf.cpp @@ -68,7 +68,7 @@ void usage(const char *name) { cout << "Firewall Builder: policy compiler for OpenBSD PF" << endl; cout << "Version " << VERSION << endl; - cout << "Usage: " << name << " [-x] [-v] [-V] [-f filename.xml] [-o output.fw] [-d destdir] [-m] [-4|-6] firewall_object_name" << endl; + cout << "Usage: " << name << " [-x] [-v] [-V] [-f filename.xml] [-o output.fw] [-d destdir] [-D datadir] [-m] [-4|-6] firewall_object_name" << endl; } diff --git a/src/pflib/CompilerDriver_pf_run.cpp b/src/pflib/CompilerDriver_pf_run.cpp index 6c3daaa9c..f0c2094ef 100644 --- a/src/pflib/CompilerDriver_pf_run.cpp +++ b/src/pflib/CompilerDriver_pf_run.cpp @@ -450,6 +450,7 @@ QString CompilerDriver_pf::run(const std::string &cluster_id, { Preprocessor_pf* prep = new Preprocessor_pf( objdb , fw, ipv6_policy); + prep->setSingleRuleCompileMode(single_rule_id); if (inTestMode()) prep->setTestMode(); if (inEmbeddedMode()) prep->setEmbeddedMode(); prep->compile(); @@ -472,7 +473,7 @@ QString CompilerDriver_pf::run(const std::string &cluster_id, if (table_factories.count(ruleset_name) == 0) { table_factories[ruleset_name] = - new fwcompiler::TableFactory(this, persistent_objects); + new fwcompiler::TableFactory(this, fw, persistent_objects); } NATCompiler_pf n( objdb, fw, ipv6_policy, oscnf.get(), @@ -547,7 +548,7 @@ QString CompilerDriver_pf::run(const std::string &cluster_id, if (table_factories.count(ruleset_name) == 0) { table_factories[ruleset_name] = - new fwcompiler::TableFactory(this, persistent_objects); + new fwcompiler::TableFactory(this, fw, persistent_objects); } PolicyCompiler_pf c( objdb, fw, ipv6_policy, oscnf.get(), diff --git a/src/pflib/TableFactory.cpp b/src/pflib/TableFactory.cpp index acdab65b0..852ab4923 100644 --- a/src/pflib/TableFactory.cpp +++ b/src/pflib/TableFactory.cpp @@ -47,9 +47,11 @@ using namespace libfwbuilder; using namespace fwcompiler; using namespace std; -TableFactory::TableFactory(BaseCompiler *comp, Library *persistent_objects) +TableFactory::TableFactory(BaseCompiler *comp, Firewall *fwall, + Library *persistent_objects) { compiler = comp; + firewall = fwall; ruleSetName = ""; dbroot = NULL; persistent_tables = new ObjectGroup(); @@ -181,9 +183,15 @@ string TableFactory::PrintTables() { output << "persist"; if ( !atrt->getSourceName().empty() ) - output << " file \"" - << atrt->getSourceName() - << "\""; + { + string path = + atrt->getSourceNameAsPath(firewall->getOptionsObject()); + if (path.empty()) { + compiler->abort("Error: Empty path or data directory for address table: " + atrt->getName()); + } + + output << " file \"" << path << "\""; + } output << endl; continue; diff --git a/src/pflib/TableFactory.h b/src/pflib/TableFactory.h index 7b4295392..b2d7ad08f 100644 --- a/src/pflib/TableFactory.h +++ b/src/pflib/TableFactory.h @@ -27,6 +27,7 @@ #define __TABLEFACTORY_HH #include +#include #include #include @@ -44,6 +45,7 @@ namespace fwcompiler { class TableFactory { BaseCompiler *compiler; + libfwbuilder::Firewall *firewall; libfwbuilder::FWObjectDatabase *dbroot; libfwbuilder::FWObject *persistent_tables; @@ -53,7 +55,7 @@ namespace fwcompiler { std::string ruleSetName; public: - TableFactory(BaseCompiler *comp, libfwbuilder::Library *persistent_objects); + TableFactory(BaseCompiler *comp, libfwbuilder::Firewall *firewall, libfwbuilder::Library *persistent_objects); void init(libfwbuilder::FWObjectDatabase *_dbroot); void detach();