Exemplo n.º 1
0
    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()));
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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);
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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);
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
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);
    }
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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 );
    }
}
Exemplo n.º 12
0
/**
 * 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;
}
Exemplo n.º 13
0
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 );
        }
    }
}
Exemplo n.º 14
0
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;
}