Exemplo n.º 1
0
/*
 * This is identical to 
 * PolicyCompiler_ipf::processMultiAddressObjectsInRE::processNext()
 * TODO: move the code to the class Compiler so it can be reused.
 */
bool RoutingCompiler::processMultiAddressObjectsInRE::processNext()
{
    RoutingRule *rule = getNext(); if (rule==NULL) return false;
    RuleElement *re = RuleElement::cast( rule->getFirstByType(re_type) );

    for (FWObject::iterator i=re->begin(); i!=re->end(); i++)
    {
        FWObject *o= *i;
        if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
        MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o);
        if (atrt!=NULL && atrt->getSubstitutionTypeName()==AddressTable::TYPENAME)
            compiler->abort(
                rule, 
                "Run-time AddressTable objects are not supported.");

        AddressTable *at = AddressTable::cast(o);
        if (at && at->isRunTime())
            compiler->abort(
                rule, 
                "Run-time AddressTable objects are not supported.");
    }

    tmp_queue.push_back(rule);
    return true;
}
void NATCompiler_ipf::PrintRule::_printAddr_L(Address  *o, bool print_netmask)
{
    FWOptions* options=compiler->fw->getOptionsObject();

    MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o);
    if (atrt!=nullptr)
    {
        if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME)
        {
            compiler->output <<  atrt->getSourceName() << " ";
            return;
        }
        // at this time we only support two types of MultiAddress
        // objects: AddressTable and DNSName. Both should be converted
        // to MultiAddressRunTime at this point. If we get some other
        // kind of MultiAddressRunTime object, we do not know what to do
        // with it so we stop.
        assert(atrt==nullptr);
    }

    if (Interface::cast(o)!=nullptr && Interface::cast(o)->isDyn()) 
    {
        if (options->getBool("dynAddr"))
            compiler->output << "(" << o->getName() << ") ";
        else
            compiler->output << "any ";

        return;
    }

    const InetAddr *addr = o->getAddressPtr();
    if (addr)
    {
        InetAddr mask = *(o->getNetmaskPtr());

        if (Interface::cast(o)!=nullptr && ! Interface::cast(o)->isDyn()) 
            mask = InetAddr(InetAddr::getAllOnes());

        if (o->dimension()==1)
            mask = InetAddr(InetAddr::getAllOnes());

        if (addr->isAny() && mask.isAny())
        {
            compiler->output << "any ";
        } else
        {

            compiler->output << addr->toString();

            if (print_netmask)
                compiler->output << "/" << mask.getLength();
            compiler->output  << " ";
        }
    }
}
Exemplo n.º 3
0
void* ObjectMatcher::dispatch(Firewall *obj1, void *_obj2)
{
    FWObject *obj2 = (FWObject*)(_obj2);
    if (obj1->getId() == obj2->getId()) return obj1;

/*
 * Special case: run-time DNSName object with source name "self"
 * matches firewall.
 */
    MultiAddressRunTime *mart = MultiAddressRunTime::cast(obj2);
    if (mart)
    {
        if (mart->getSubstitutionTypeName() == DNSName::TYPENAME &&
            mart->getSourceName() == "self")
            return obj1;
    }

/*
 *  match only if all interfaces of obj1 match obj2
 */
    return dispatch(static_cast<Host*>(obj1), obj2);
}
void NATCompiler_pf::PrintRule::_printAddr(FWObject *o)
{
    MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o);
    if (atrt!=NULL)
    {
        if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME)
        {
            compiler->output <<  atrt->getSourceName() << " ";
            return;
        }
        if (atrt->getSubstitutionTypeName()==AddressTable::TYPENAME)
        {
            compiler->output << "<" << o->getName() << "> ";
            return;
        }
        if (atrt->getSubstitutionTypeName()==AttachedNetworks::TYPENAME)
        {
            compiler->output << atrt->getSourceName() << ":network ";
            return ;
        }

        assert(atrt==NULL);
    }

    if (Interface::cast(o)!=NULL)
    {
        compiler->output << "(" << o->getName() << ") ";
        return;
    }

    if (o->getBool("pf_table"))
    {
        compiler->output << "<" << o->getName() << "> ";
        return;
    }

    Address *addr_obj = Address::cast(o);
    assert(addr_obj!=NULL);

    const InetAddr *addr = addr_obj->getAddressPtr();
    if (addr)
    {
        InetAddr mask = *(addr_obj->getNetmaskPtr());

        if (Interface::cast(o)!=NULL || Address::cast(o)->dimension()==1)
        {
            mask = InetAddr(InetAddr::getAllOnes());
        }

        if (addr->isAny() && mask.isAny())
        {
            compiler->output << "any ";
        } else
        {
            compiler->output << addr->toString();
            if (!mask.isHostMask())
            {
                compiler->output << "/" << mask.getLength();
            }
            compiler->output  << " ";
        }
    }
}
Exemplo n.º 5
0
string TableFactory::PrintTables()
{
    if (tables.size() == 0) return "";

    stringstream output;
    output << endl;
    output << "# Tables: (" << tables.size() << ")" << endl;

    for (map<string,string>::const_iterator i=tblnames.begin();
         i!=tblnames.end(); i++)
    {
        string tblID = i->second;
        FWObject *grp = tables[tblID];
        output << "table ";
        output << "<" << grp->getName() << "> ";
        MultiAddressRunTime *atrt = MultiAddressRunTime::cast(grp);
        if (atrt!=nullptr &&
            atrt->getSubstitutionTypeName()==AddressTable::TYPENAME)
        {
            output << "persist";
            if ( !atrt->getSourceName().empty() )
            {
                string path =
                    atrt->getSourceNameAsPath(firewall->getOptionsObject());
                if (path.empty()) {
                    compiler->abort("Error: Firewall's data directory not set for address table: " + atrt->getName());
                }
                
                output << " file \"" << path << "\"";
            }

            output << endl;
            continue;
        }
        output << "{ ";
        for (FWObject::iterator i=grp->begin(); i!=grp->end(); i++)
        {
            if (i!=grp->begin())  output << ", ";
            FWObject *o = FWReference::getObject(*i);
            if (o==nullptr) compiler->abort("broken table object ");

            MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o);
            if (atrt!=nullptr)
            {
                if (atrt->getSubstitutionTypeName()==DNSName::TYPENAME)
                {
                    output <<  atrt->getSourceName() << " ";
                }
                if (atrt->getSubstitutionTypeName()==AttachedNetworks::TYPENAME)
                {
                    output << atrt->getSourceName() << ":network ";
                }
            } else
            {
                if (Interface::cast(o))
                {
                    output << o->getName();
                } else
                {
                    Address *A=Address::cast( o );
                    if (A==nullptr)
                        compiler->abort("table object must be an address: '" +
                                          o->getTypeName()+"'");

                    const InetAddr *addr = A->getAddressPtr();
                    InetAddr mask = *(A->getNetmaskPtr());

                    if (A->dimension()==1)
                    {
                        mask = InetAddr(InetAddr::getAllOnes());
                    }

                    output << addr->toString();
                    if (!mask.isHostMask())
                    {
                        output << "/" << mask.getLength();
                    }
                }
            }
            output << " ";
        }
        output << "} ";
        output << endl;
    }
    output << endl;
    return output.str();
}
bool PolicyCompiler_pf::processMultiAddressObjectsInRE::processNext()
{
    PolicyCompiler_pf *pf_comp=dynamic_cast<PolicyCompiler_pf*>(compiler);
    PolicyRule *rule=getNext(); if (rule==NULL) return false;

    RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) );
    bool neg = re->getNeg();

    list<FWObject*> maddr_runtime;

    try
    {
        for (FWObject::iterator i=re->begin(); i!=re->end(); i++)
        {
            FWObject *o= *i;
            if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();

            MultiAddressRunTime *atrt = MultiAddressRunTime::cast(o);
            if (atrt!=NULL &&
                atrt->getSubstitutionTypeName()==AddressTable::TYPENAME)
            {
                if (re->size()>1 && neg)
                {
                    compiler->abort(rule,
                                    "AddressTable object can not be used "
                                    "with negation in combination with "
                                    "other objects in the same rule element.");
                }
                string tblname = o->getName();
                string tblID = tblname + "_addressTableObject";
                pf_comp->tables->registerTable(tblname,tblID,o);
                o->setBool("pf_table",true);
                maddr_runtime.push_back(o);
            }
        }
    } catch(FWException &ex)  // TableFactory::registerTable throws exception
    {
        string err;
        err = "Can not process MultiAddress object: " + ex.toString();
        compiler->abort(rule, err);
    }

    if (!maddr_runtime.empty())
    {
        RuleElement *nre;

        for (FWObject::iterator i=maddr_runtime.begin(); i!=maddr_runtime.end(); i++)
        {
            PolicyRule *r= compiler->dbcopy->createPolicyRule();
            compiler->temp_ruleset->add(r);
            r->duplicate(rule);
            nre=RuleElement::cast( r->getFirstByType(re_type) );
            nre->clearChildren();
            nre->addRef( *i );
            tmp_queue.push_back(r);
        }

        for (FWObject::iterator i=maddr_runtime.begin(); i!=maddr_runtime.end(); i++)
            re->removeRef( *i );

        if (!re->isAny())
            tmp_queue.push_back(rule);

        return true;
    }

    tmp_queue.push_back(rule);
    return true;
}
/*
 * this is very much like
 * Compiler::swapMultiAddressObjectsInRE::processNext() except it also
 * registers the table using registerTable()
 */
bool PolicyCompiler_pf::swapAddressTableObjectsInRE::processNext()
{
    PolicyCompiler_pf *pf_comp=dynamic_cast<PolicyCompiler_pf*>(compiler);
    Rule *rule=prev_processor->getNextRule(); if (rule==NULL) return false;

    RuleElement *re=RuleElement::cast( rule->getFirstByType(re_type) );

    list<MultiAddress*> cl;
    for (FWObject::iterator i=re->begin(); i!=re->end(); i++)
    {
        FWObject *o= *i;
        if (FWReference::cast(o)!=NULL) o=FWReference::cast(o)->getPointer();
        /* 
         * All addressTable objects will be run-time here because we
         * switch them in preprocessor. The difference is: if address
         * table was originally run-time, at this point it will have
         * no children, however if it was compile-time originally, it
         * will have children objects.  That is how we distinguish
         * them in this rule processor. Here we only deal with
         * AddressTable objects that originally used to be
         * compile-time because we need to create tables for them.
         */
        if (AddressTable::cast(o)!=NULL &&
            AddressTable::cast(o)->isRunTime() &&
            o->size() > 0)
            cl.push_back(MultiAddress::cast(o));
    }

    if (!cl.empty())
    {
        for (list<MultiAddress*>::iterator i=cl.begin(); i!=cl.end(); i++)
        {
            MultiAddress *atbl = *i;

            // Need to make sure the ID of the MultiAddressRunTime
            // object created here is stable and is always the same
            // for the same MultiAddress object. In particular this
            // ensures that we reuse tables between policy and NAT rules
            string mart_id_str = FWObjectDatabase::getStringId(atbl->getId()) +
                "_runtime";
            int mart_id = FWObjectDatabase::registerStringId(mart_id_str);

            MultiAddressRunTime *mart = 
                MultiAddressRunTime::cast(compiler->dbcopy->findInIndex(mart_id));
            if (mart==NULL)
            {
                mart = new MultiAddressRunTime(atbl);

                // need to ensure stable ID for the runtime object, so
                // that when the same object is replaced in different
                // rulesets by different compiler passes, chosen
                // runtime object has the same ID and is identified as
                // the same by the compiler.

                mart->setId( mart_id );
                compiler->dbcopy->addToIndex(mart);
                compiler->persistent_objects->add(mart);

// register this object as a table
                string tblname = atbl->getName();
                string tblID = tblname + "_addressTableObject";
                pf_comp->tables->registerTable(tblname,tblID,atbl);
            }

            re->removeRef(atbl);
            re->addRef(mart);
        }
        tmp_queue.push_back(rule);
        return true;
    }

    tmp_queue.push_back(rule);
    return true;
}