bool operator<( const QTreeWidgetItem & other ) const { int col = this->treeWidget()->sortColumn(); if ( col != 1) return this->text(col) < other.text(col); FWObject *otherobj = db->findInIndex(other.data(0, Qt::UserRole).toInt()); FWObject *thisobj = db->findInIndex(this->data(0, Qt::UserRole).toInt()); if (otherobj->getTypeName() != thisobj->getTypeName()) return thisobj->getTypeName() < otherobj->getTypeName(); if (IPv4::isA(thisobj) || IPv6::isA(thisobj)) { return compare_addrs(Address::cast(thisobj)->getAddressPtr(), Address::cast(otherobj)->getAddressPtr()); } if (Service::isA(thisobj)) { return Service::cast(thisobj)->getProtocolNumber() < Service::cast(otherobj)->getProtocolNumber(); } if(AddressRange::isA(thisobj)) { return compare_addrs(&AddressRange::cast(thisobj)->getRangeStart(), &AddressRange::cast(otherobj)->getRangeStart()); } if (Host::isA(thisobj)) { return compare_addrs(Host::cast(thisobj)->getAddressPtr(), Host::cast(otherobj)->getAddressPtr()); } return this->text(col) < other.text(col); }
void FirewallInstaller::executeExternalInstallScript(const QString &command, const QString &script_args) { FWObjectDatabase *db = cnf->fwobj->getRoot(); assert(db); QString wdir = getFileDir( mw->getRCS()->getFileName() ); QStringList args; //args.push_back(command.trimmed()); args.push_back("-f"); args.push_back(db->getFileName().c_str()); if (wdir!="") { args.push_back("-d"); args.push_back(wdir); } args += script_args.trimmed().split(" ", QString::SkipEmptyParts); args.push_back(cnf->fwobj->getName().c_str()); if (cnf->verbose) inst_dlg->displayCommand(args); qApp->processEvents(); inst_dlg->setUpProcessToInstall(); if (!inst_dlg->executeCommand(command.trimmed(), args)) QTimer::singleShot( 0, inst_dlg, SLOT(mainLoopInstall())); }
void Importer::newNATRule() { if (fwbdebug) qDebug() << "Importer::newNATRule()"; FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); FWObject *nobj = dbroot->create(NATRule::TYPENAME); current_rule = Rule::cast(nobj); if (fwbdebug) qDebug() << "current_rule=" << current_rule; }
void PolicyRule::setDummySource() { FWObjectDatabase *root = getRoot(); FWObject *dummySource = root->findInIndex(FWObjectDatabase::DUMMY_ADDRESS_ID); if (!dummySource || (root->getStringId(dummySource->getId()) != "dummyaddressid0")) return; FWObject::iterator i1 = begin(); (*i1)->addRef(dummySource); src_re = RuleElementSrc::cast(*i1); }
void PolicyRule::setDummyDestination() { FWObjectDatabase *root = getRoot(); FWObject *dummyDestination = root->findInIndex(FWObjectDatabase::DUMMY_ADDRESS_ID); if (!dummyDestination || (root->getStringId(dummyDestination->getId()) != "dummyaddressid0")) return; FWObject::iterator i1 = begin(); i1++; (*i1)->addRef(dummyDestination); dst_re = RuleElementDst::cast(*i1); }
void Importer::newPolicyRule() { if (fwbdebug) qDebug() << "Importer::newPolicyRule()"; FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); FWObject *nobj = dbroot->create(PolicyRule::TYPENAME); current_rule = Rule::cast(nobj); // check if all child objects were populated properly FWOptions *ropt = current_rule->getOptionsObject(); assert(ropt!=NULL); ropt->setBool("stateless", true); }
void PolicyRule::setDummyService() { FWObjectDatabase *root = getRoot(); FWObject *dummyService = root->findInIndex(FWObjectDatabase::DUMMY_SERVICE_ID); if (!dummyService || (root->getStringId(dummyService->getId()) != "dummyserviceid0")) return; FWObject::iterator i1 = begin(); i1++; i1++; (*i1)->addRef(dummyService); srv_re = RuleElementSrv::cast(*i1); }
void PolicyRule::setDummyInterface() { FWObjectDatabase *root = getRoot(); FWObject *dummyInterface = root->findInIndex(FWObjectDatabase::DUMMY_INTERFACE_ID); if (!dummyInterface || (root->getStringId(dummyInterface->getId()) != "dummyinterfaceid0")) return; FWObject::iterator i1 = begin(); i1++; i1++; i1++; (*i1)->addRef(dummyInterface); itf_re = RuleElementItf::cast(*i1); }
void DynamicGroup::loadFromSource(bool ipv6, FWOptions *options, bool test_mode) throw (FWException) { FWObjectDatabase *root = getRoot(); FWObject::tree_iterator tree_iter; for (tree_iter = root->tree_begin(); tree_iter != root->tree_end(); ++tree_iter) { FWObject *elem = (*tree_iter); if (elem == root) continue; if (!isMemberOfGroup(elem)) continue; addRef(elem); } }
UnidirectionalRuleSet* Importer::getUnidirRuleSet( const std::string &ruleset_name, const string &ruleset_type_name) { UnidirectionalRuleSet *rs = all_rulesets[ruleset_name]; if (rs==NULL) { // got 'ip access-group' command before the access list was defined rs = new UnidirectionalRuleSet(); rs->name = ruleset_name; FWObjectDatabase *dbroot = getFirewallObject()->getRoot(); rs->ruleset = RuleSet::cast(dbroot->create(ruleset_type_name)); rs->ruleset->setName(ruleset_name); all_rulesets[ruleset_name] = rs; // add this ruleset to the firewall temporarily // because ruleset must belong to the tree somewhere in // order for other objects to be added properly. getFirewallObject()->add(rs->ruleset); } return rs; }
void ProjectPanel::exportLibraryTo(QString fname,list<FWObject*> &selectedLibs, bool rof) { QApplication::setOverrideCursor( QCursor( Qt::WaitCursor) ); FWObjectDatabase *ndb = db()->exportSubtree( selectedLibs ); QApplication::restoreOverrideCursor(); if (rof) { for (list<FWObject*>::iterator i=selectedLibs.begin(); i!=selectedLibs.end(); ++i) { FWObject *nlib= ndb->findInIndex( (*i)->getId() ); if (nlib && nlib->getId()!=FWObjectDatabase::DELETED_OBJECTS_ID) nlib->setReadOnly( true ); } } try { xmlSetCompressMode(st->getCompression() ? 9 : 0); ndb->saveFile( fname.toLocal8Bit().constData() ); } catch (FWException &ex) { /* error saving the file. Since XMLTools does not return any useful * error message in the exception, let's check for obvious problems here */ QString err; if (access( fname.toLocal8Bit().constData(), W_OK)!=0 && errno==EACCES) err=QObject::tr("File is read-only"); QMessageBox::critical( this,"Firewall Builder", QObject::tr("Error saving file %1: %2") .arg(fname).arg(err), "&Continue", QString::null, QString::null, 0, 1 ); } }
/** * Load library or several libraries from an external file. Return * pointer to the last new imported library. */ FWObject* ProjectPanel::loadLibrary(const string &libfpath) { MessageBoxUpgradePredicate upgrade_predicate(mainW); FWObject *last_new_lib = nullptr; try { FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->load(libfpath, &upgrade_predicate, Constants::getDTDDirectory()); FWObject *dobj = ndb->findInIndex(FWObjectDatabase::DELETED_OBJECTS_ID); if (dobj) ndb->remove(dobj, false); set<int> duplicate_ids; db()->findDuplicateIds(ndb, duplicate_ids); map<int, int> id_mapping; for (set<int>::iterator it=duplicate_ids.begin(); it!=duplicate_ids.end(); ++it) { FWObject *obj = ndb->findInIndex(*it); assert(obj!=nullptr); int new_id = FWObjectDatabase::generateUniqueId(); obj->setId(new_id); id_mapping[*it] = new_id; // cerr << "Duplicate ID: " << *it // << " " << FWObjectDatabase::getStringId(*it) // << obj->getPath() // << endl; } ndb->fixReferences(ndb, id_mapping); int new_lib_id = -1; // check for duplicate library names FWObjectTypedChildIterator it2 = ndb->findByType(Library::TYPENAME); for (; it2!=it2.end(); ++it2) { QString new_name = m_panel->om->makeNameUnique( db(), QString::fromUtf8((*it2)->getName().c_str()), Library::TYPENAME); (*it2)->setName(string(new_name.toUtf8())); if ((*it2)->getId() != FWObjectDatabase::STANDARD_LIB_ID) new_lib_id = (*it2)->getId(); } MergeConflictRes mcr(this); db()->merge(ndb, &mcr); delete ndb; last_new_lib = db()->findInIndex(new_lib_id); } catch(FWException &ex) { QString error_txt = ex.toString().c_str(); if (error_txt.length() > LONG_ERROR_CUTOFF) { error_txt.truncate(LONG_ERROR_CUTOFF); error_txt += "\n\n" + tr("(Long error message was truncated)"); } QMessageBox::critical( this,"Firewall Builder", tr("The program encountered error trying to load file %1.\n" "The file has not been loaded. Error:\n%2"). arg(libfpath.c_str()).arg(error_txt), tr("&Continue"), QString::null,QString::null, 0, 1 ); } return last_new_lib; }
void ProjectPanel::save() { if (fwbdebug) qDebug("ProjectPanel::save: rcs=%p rcs->isRO=%d " "rcs->isTemp=%d rcs->getFileName=%s", rcs, rcs->isRO(), rcs->isTemp(), rcs->getFileName().toLocal8Bit().constData()); //undoStack->clear(); if (!rcs->isRO() && !rcs->isTemp()) { try { if (rcs->getFileName().isEmpty()) fileSaveAs(); // eventually calls this method again else { /* editingLibfile is true if user edits a library or master library file */ mw->showStatusBarMessage( tr("Saving data to file %1").arg(rcs->getFileName())); bool editingLibfile = editingLibrary(); /* **************************************************************** * * REMOVE THIS * * or may be not. The savings of not storing standard objects in each file * are minimal but this code seems to be leaking too * ****************************************************************** */ //if (st->getDontSaveStdLib()) // this is now default if (false) { list<FWObject*> userLibs; list<FWObject*> ll = db()->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { if (fwbdebug) qDebug("ProjectPanel::save() lib %s", (*i)->getName().c_str() ); /* skip standard and template libraries unless we edit them */ int id = (*i)->getId(); if (id==FWObjectDatabase::STANDARD_LIB_ID && !editingStandardLib) continue; if (id==FWObjectDatabase::TEMPLATE_LIB_ID && !editingTemplateLib) continue; if (fwbdebug) qDebug(" add"); userLibs.push_back( *i ); } QApplication::setOverrideCursor(QCursor( Qt::WaitCursor)); FWObjectDatabase *ndb = db()->exportSubtree(userLibs); if (editingLibfile) { /* exported libraries are always read-only */ list<FWObject*> ll = ndb->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { if ((*i)->getId()!=FWObjectDatabase::STANDARD_LIB_ID && (*i)->getId()!=FWObjectDatabase::DELETED_OBJECTS_ID) (*i)->setReadOnly( true ); } } ndb->resetTimeLastModified( db()->getTimeLastModified() ); xmlSetCompressMode(st->getCompression() ? 9 : 0); ndb->saveFile( rcs->getFileName().toLocal8Bit().constData()); delete ndb; QApplication::restoreOverrideCursor(); // reset "dirty" flag only after we actually save the data // fixes #389 db()->setDirty(false); // and reset actions, including Save() which should now // be inactive QCoreApplication::postEvent(mw, new updateGUIStateEvent()); //mw->prepareFileMenu(); } else { QApplication::setOverrideCursor(QCursor( Qt::WaitCursor)); xmlSetCompressMode(st->getCompression() ? 9 : 0); db()->saveFile( rcs->getFileName().toLocal8Bit().constData()); QApplication::restoreOverrideCursor(); } } } catch (FWException &ex) { QApplication::restoreOverrideCursor(); /* error saving the file. Since XMLTools does not return any useful * error message in the exception, let's check for obvious problems here */ QString err; if (access( rcs->getFileName().toLocal8Bit().constData(), W_OK)!=0 && errno==EACCES) err=tr("File is read-only"); else err=ex.toString().c_str(); QMessageBox::critical( this,"Firewall Builder", tr("Error saving file %1: %2") .arg(rcs->getFileName()).arg(err), tr("&Continue"), QString::null, QString::null, 0, 1 ); } } }
bool ProjectPanel::loadFromRCS(RCS *_rcs) { resetFD(); editingStandardLib = false; editingTemplateLib = false; bool forceSave=false; // use this flag to force 'save' operation if file should be renamed MessageBoxUpgradePredicate upgrade_predicate(mainW); assert(_rcs!=nullptr); rcs = _rcs; try { /* load the data file */ systemFile = false; clearObjects(); if (objdb) { objdb->destroyChildren(); delete objdb; } objdb = new FWObjectDatabase(); // need to drop read-only flag on the database before I load new objects objdb->setReadOnly( false ); // always loading system objects mw->showStatusBarMessage(tr("Loading system objects...") ); objdb->load( Constants::getStandardObjectsFilePath(), &upgrade_predicate, Constants::getDTDDirectory()); objdb->setFileName(""); // objects from a data file are in database ndb mw->showStatusBarMessage(tr("Reading and parsing data file...")); FWObjectDatabase *ndb = new FWObjectDatabase(); ndb->load(rcs->getFileName().toLocal8Bit().constData(), &upgrade_predicate,Constants::getDTDDirectory()); time_t oldtimestamp = ndb->getTimeLastModified(); /* loadingLib is true if user wants to open a library or master library file */ bool loadingLib = editingLibrary(); if (fwbdebug) { list<FWObject*> ll = ndb->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { qDebug("* Found library %s %s in the data file", FWObjectDatabase::getStringId((*i)->getId()).c_str(), (*i)->getName().c_str() ); } } /* if user opens library file, clear read-only flag so they can edit it */ if (loadingLib) { list<FWObject*> ll = ndb->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { if ((*i)->getId()==FWObjectDatabase::STANDARD_LIB_ID) editingStandardLib=true; if ((*i)->getId()==FWObjectDatabase::TEMPLATE_LIB_ID) editingTemplateLib=true; (*i)->setReadOnly( false ); } } mw->showStatusBarMessage(tr("Merging with system objects...") ); MergeConflictRes mcr(mainW); objdb->merge(ndb, &mcr); ndb->destroyChildren(); delete ndb; objdb->setFileName(rcs->getFileName().toLocal8Bit().constData()); objdb->resetTimeLastModified(oldtimestamp); objdb->setDirty(false); if (fwbdebug) { qDebug("* Merge is done"); list<FWObject*> ll = db()->getByType(Library::TYPENAME); for (FWObject::iterator i=ll.begin(); i!=ll.end(); i++) { qDebug("* Library %s %s in the data file", FWObjectDatabase::getStringId((*i)->getId()).c_str(), (*i)->getName().c_str() ); } } /* this is a hack: 'Standard' library should be read-only. I * have too many files I already converted to the new API/DTD * and I am too lazy to convert them again, so I patch it up * here. * * However, if I am editing standard library, it should not be * read-only. */ FWObject *slib = objdb->findInIndex(FWObjectDatabase::STANDARD_LIB_ID); if (slib!=nullptr ) { if (fwbdebug) qDebug("standard library read-only status: %d, " "editingStandardLib: %d", slib->isReadOnly(), editingStandardLib); slib->setReadOnly(! editingStandardLib); } /* if the file name has an old extension .xml, change it to .fwb and * warn the user */ QString fn = rcs->getFileName(); QFileInfo ofinfo(fn); if ( ofinfo.suffix()=="xml") { if (fwbdebug) { qDebug("Need to rename file: %s", fn.toLatin1().constData()); qDebug(" dirPath: %s", ofinfo.dir().absolutePath().toLatin1().constData()); qDebug(" filePath: %s", ofinfo.absoluteFilePath().toLatin1().constData()); } QString newFileName = ofinfo.dir().absolutePath() + "/" + ofinfo.completeBaseName() + ".fwb"; bool needToRename = true; /* need these dances with symlinks to fix bug #1008956: * "Existing .fwb file gets overwritten if has wrong * extension" */ QFileInfo nfinfo(newFileName); if (nfinfo.exists() && ofinfo.isSymLink() && ofinfo.readLink()==newFileName) { // .xml file is a symlink pointing at .fwb file // no need to rename needToRename = false; } if (needToRename) { if (nfinfo.exists()) { /* .fwb file exists but .xml is not a symlink * .fwb is a separate file with the same name. * * tell the user we need to rename old file but * the new file exists, then ask them to choose a * new name. If the user chooses the same name and * agrees to overwrite the file, just use this * name. If the user hits cancel, tell them they * need to choose a new name and open "file save" * dialog again. * * Show the first dialog only once. If user hits * Cancel, they see shorted version of the dialog * and will be presented with "save file" dialog * again. */ QMessageBox::warning( this,"Firewall Builder", tr("Firewall Builder uses file extension '.fwb' and\n" "needs to rename old data file '%1' to '%2',\n" "but file '%3' already exists.\n" "Choose a different name for the new file.") .arg(fn).arg(newFileName).arg(newFileName), tr("&Continue"), QString::null,QString::null, 0, 1 ); newFileName = chooseNewFileName( fn, tr("Choose name and location for the new file")); if (newFileName.isEmpty()) { QString oldFileName = ofinfo.absoluteFilePath() + ".bak"; rename(oldFileName.toLocal8Bit().constData(), fn.toLocal8Bit().constData()); QMessageBox::warning( this,"Firewall Builder", tr("Load operation cancelled and data file reverted" "to original version."), tr("&Continue"), QString::null,QString::null, 0, 1 ); loadStandardObjects(); return false; } nfinfo.setFile(newFileName); } rename(fn.toLocal8Bit().constData(), newFileName.toLocal8Bit().constData()); QMessageBox::warning( this,"Firewall Builder", tr("Firewall Builder uses file extension '.fwb'. Your data" "file '%1' \nhas been renamed '%2'") .arg(fn).arg(newFileName), tr("&Continue"), QString::null,QString::null, 0, 1 ); } fn = newFileName; } rcs->setFileName(fn); db()->setFileName(fn.toLocal8Bit().constData()); //setWindowTitle(getPageTitle()); //QCoreApplication::postEvent(mw, new updateSubWindowTitlesEvent()); mainW->disableActions(m_panel->ruleSets->count()!=0); time_t last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::load(): load complete dirty=%d " "last_modified=%s", db()->isDirty(), ctime(&last_modified)); } catch(FWException &ex) { QString trans = ex.getProperties()["failed_transformation"].c_str(); QString elem = ex.getProperties()["failed_element"].c_str(); if(!trans.isEmpty() || !elem.isEmpty()) { QString msg = tr("Exception: %1").arg(ex.toString().c_str()); if (!trans.isEmpty()) { trans.truncate(LONG_ERROR_CUTOFF); msg+="\n"+tr("Failed transformation : %1").arg(trans); } if (!elem.isEmpty()) { elem.truncate(LONG_ERROR_CUTOFF); msg+="\n"+tr("XML element : %1").arg(elem); } QMessageBox::critical( this,"Firewall Builder", tr("The program encountered error trying to load data file.\n" "The file has not been loaded. Error:\n%1").arg(msg), tr("&Continue"), QString::null,QString::null, 0, 1 ); } else { // this was not XML error, perhaps permissions or other // filesystem problem QString error_txt = QString::fromUtf8(ex.toString().c_str()); if (error_txt.length() > LONG_ERROR_CUTOFF) { error_txt.truncate(LONG_ERROR_CUTOFF); error_txt += "\n\n" + tr("(Long error message was truncated)"); } QMessageBox::critical( this,"Firewall Builder", tr("The program encountered error trying to load data file.\n" "The file has not been loaded. Error:\n%1").arg( error_txt), tr("&Continue"), QString::null,QString::null, 0, 1 ); } // load standard objects so the window does not remain empty loadStandardObjects(); return false; } db()->setReadOnly( rcs->isRO() || rcs->isTemp() ); // clear dirty flag for all objects, recursively if (!forceSave) db()->setDirty(false); mw->showStatusBarMessage(tr("Building object tree...")); QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 100); loadObjects(); QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents, 100); mw->showStatusBarMessage(tr("Indexing...") ); db()->reIndex(); setupAutoSave(); time_t last_modified = db()->getTimeLastModified(); if (fwbdebug) qDebug("ProjectPanel::load(): all done: " "dirty=%d last_modified=%s", db()->isDirty(), ctime(&last_modified)); return true; }