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();