You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
379 lines
13 KiB
379 lines
13 KiB
/***************************************************************************
|
|
begin : Tue Aug 20 2002
|
|
copyright : (C) 2002 by Christian Hubinger
|
|
email : chubinger@irrsinnig.org
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "iptable.h"
|
|
|
|
// TQt includes
|
|
#include <tqstring.h>
|
|
#include <tqregexp.h>
|
|
|
|
// kde includes
|
|
#include <kdebug.h>
|
|
#include <tdelocale.h>
|
|
|
|
// project includes
|
|
#include "kmfcheckinput.h"
|
|
#include "iptchain.h"
|
|
#include "kmferror.h"
|
|
#include "kmfiptdoc.h"
|
|
#include "xmlnames.h"
|
|
|
|
namespace KMF {
|
|
|
|
IPTable::IPTable( KMFIPTDoc* doc, const char* name, const TQString& tableName ) : NetfilterObject( doc, name ) {
|
|
// kdDebug() << "IPTable::IPTable(TQString& name)" << endl;
|
|
kmfdoc = doc;
|
|
// m_object_type = NetfilterObject::TABLE;
|
|
m_err = new KMFError();
|
|
m_chains.setAutoDelete( false );
|
|
setName( tableName );
|
|
}
|
|
|
|
IPTable::~IPTable() {
|
|
kdDebug() << "\n\nIPTable::~IPTable() : " << name() << endl;
|
|
clear();
|
|
}
|
|
|
|
int IPTable::type() {
|
|
// kdDebug() << "IPTable::type()" << endl;
|
|
return NetfilterObject::TABLE;
|
|
}
|
|
void IPTable::clear() {
|
|
m_chains.setAutoDelete( true );
|
|
m_chains.clear();
|
|
m_chains.setAutoDelete( false );
|
|
}
|
|
void IPTable::reset() {
|
|
// kdDebug() << "void IPTable::resetTable()" << endl;
|
|
TQPtrListIterator<IPTChain> it ( m_chains );
|
|
while ( it.current() ) {
|
|
IPTChain* chain = it.current();
|
|
if ( chain->isBuildIn() ) {
|
|
chain->reset();
|
|
++it;
|
|
} else {
|
|
m_chains.remove( chain );
|
|
}
|
|
}
|
|
changed();
|
|
}
|
|
|
|
void IPTable::settupDefaultChains() {
|
|
// kdDebug() << "void IPTable::settupDefaultChains()" << endl;
|
|
TQString target = "ACCEPT";
|
|
IPTChain* chain = 0;
|
|
if ( name() == Constants::FilterTable_Name ) {
|
|
|
|
setDescription( i18n("This table is the main table for filtering\n"
|
|
"packets. Here you may define your\n"
|
|
"access control rules") );
|
|
|
|
|
|
chain = addChain( Constants::InputChain_Name, target, true, m_err );
|
|
// if ( chain ) {
|
|
chain->setDescription( i18n( "In this chain you can filter packets that\n"
|
|
"are addressed directly to this computer." ) );
|
|
// }
|
|
chain = addChain( Constants::OutputChain_Name, target, true, m_err );
|
|
if ( chain ) {
|
|
chain->setDescription( i18n( "In this chain you can decide which\n"
|
|
"packets are allowed to be sent away\n"
|
|
"from this computer." ) );
|
|
}
|
|
chain = addChain( Constants::ForwardChain_Name, target, true, m_err );
|
|
if ( chain ) {
|
|
chain->setDescription( i18n( "In this chain you can filter the packets\n"
|
|
"that are routed to other hosts by this\n"
|
|
"computer." ) );
|
|
}
|
|
|
|
} else if ( name() == Constants::NatTable_Name ) {
|
|
setDescription( i18n("This table is made for every kind of\n"
|
|
"NAT (Network Address Translation).") );
|
|
|
|
chain = addChain( Constants::OutputChain_Name, target, true, m_err );
|
|
if ( chain ) {
|
|
chain->setDescription( i18n( "In this chain you can decide which\n"
|
|
"packets are allowed to be sent away\n"
|
|
"from this computer." ) );
|
|
}
|
|
chain = addChain( Constants::PreRoutingChain_Name, target, true, m_err );
|
|
if ( chain )
|
|
chain->setDescription( i18n( "..." ) );
|
|
|
|
chain = addChain( Constants::PostRoutingChain_Name, target, true, m_err );
|
|
if ( chain ) {
|
|
chain->setDescription( i18n( "..." ) );
|
|
}
|
|
|
|
} else if ( name() == Constants::MangleTable_Name ) {
|
|
setDescription( i18n("This table is made for altering packets.") );
|
|
|
|
chain = addChain( Constants::InputChain_Name, target, true, m_err );
|
|
if ( chain ) {
|
|
chain->setDescription( i18n( "In this chain you can filter packets that\n"
|
|
"are addressed directly to this compter." ) );
|
|
}
|
|
chain = addChain( Constants::OutputChain_Name, target, true, m_err );
|
|
if ( chain ) {
|
|
chain->setDescription( i18n( "In this chain you can decide which\n"
|
|
"packets are allowed to be sent away\n"
|
|
"from this computer." ) );
|
|
}
|
|
chain = addChain( Constants::ForwardChain_Name, target, true, m_err );
|
|
if ( chain ) {
|
|
chain->setDescription( i18n( "In this chain you can filter the packets\n"
|
|
"that are routed to other hosts by this\n"
|
|
"computer." ) );
|
|
}
|
|
chain = addChain( Constants::PreRoutingChain_Name, target, true, m_err );
|
|
if ( chain ) {
|
|
chain->setDescription( i18n( "..." ) );
|
|
}
|
|
chain = addChain( Constants::PostRoutingChain_Name, target, true, m_err );
|
|
if ( chain ) {
|
|
chain->setDescription( i18n( "..." ) );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
IPTChain* IPTable::chainForName( const TQString& name ) {
|
|
IPTChain * tmp_chain;
|
|
for ( tmp_chain = m_chains.first();tmp_chain; tmp_chain = m_chains.next() ) {
|
|
if ( tmp_chain->name() == name )
|
|
return tmp_chain;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
IPTChain* IPTable::chainForUuid( const TQUuid& id ) {
|
|
IPTChain * tmp_chain;
|
|
for ( tmp_chain = m_chains.first(); tmp_chain; tmp_chain = m_chains.next() ) {
|
|
if ( tmp_chain->uuid() == id )
|
|
return tmp_chain;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
TQPtrList<IPTChain>& IPTable::chains() const {
|
|
TQPtrList<IPTChain>* ret_val = new TQPtrList<IPTChain>;
|
|
*ret_val = m_chains;
|
|
return *ret_val;
|
|
}
|
|
|
|
IPTChain* IPTable::addChain( const TQString& chain_name, const TQString& chain_target, bool builtin, KMFError *err ) {
|
|
// kdDebug() << "KMFError* IPTable::addChain( TQString& chain_name,TQString& chain_table,TQString& chain_target,bool builtin )" << endl;
|
|
KMFCheckInput* check = new KMFCheckInput();
|
|
check->checkInput( chain_name, "CHAINNAME", err );
|
|
if ( err->errNum() != 0 ) {
|
|
return 0;
|
|
}
|
|
|
|
TQPtrListIterator<IPTChain> it ( m_chains );
|
|
while ( it.current() ) {
|
|
IPTChain* tmp_chain = it.current();
|
|
++it;
|
|
TQString found_name = tmp_chain->name();
|
|
if ( found_name == chain_name ) {
|
|
const TQString msg = i18n( "<qt><p>Chain: <b>%1</b> already exists in table: <b>%2</b>.<br>"
|
|
"Please try again with another name. A chain name must be unique in a table.</p></qt>" ).arg( found_name ).arg( name() );
|
|
err->setErrType( KMFError::NORMAL );
|
|
err->setErrMsg( msg );
|
|
kdDebug() << "\n\nWARNING: Couldn't add chain because of dupilcate name\n\n" << endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
IPTChain * chain = new IPTChain( this, chain_name.latin1(), chain_name, builtin );
|
|
if ( builtin && chain_target != TQString() )
|
|
chain->setDefaultTarget( chain_target );
|
|
// kdDebug() << "Adding Chain: " << chain->name() << endl;
|
|
m_chains.append( chain );
|
|
changed();
|
|
err->setErrType( KMFError::OK );
|
|
return chain;
|
|
}
|
|
|
|
KMFError* IPTable::delChain( IPTChain *chain ) {
|
|
// kdDebug() << "KMFError* IPTable::delChain( IPTChain *chain )" << endl;
|
|
m_err = new KMFError();
|
|
TQString name = chain->name();
|
|
if ( chain->isBuildIn() ) {
|
|
const TQString msg = i18n( "Cannot delete built-in chain: %1" ).arg( name );
|
|
m_err->setErrMsg( msg );
|
|
m_err->setErrType( KMFError::NORMAL );
|
|
return m_err;
|
|
}
|
|
int index = m_chains.find( chain );
|
|
// kdDebug() << "fount chain nr: " << index << endl;
|
|
if ( index < 0 ) {
|
|
chain->deleteLater();
|
|
const TQString msg = i18n( "Cannot delete nonexistent chain" );
|
|
m_err->setErrMsg( msg );
|
|
m_err->setErrType( KMFError::NORMAL );
|
|
|
|
return m_err;
|
|
} else {
|
|
m_chains.remove( index );
|
|
chain->deleteLater();
|
|
const TQString msg = "";
|
|
m_err->setErrMsg( msg );
|
|
m_err->setErrType( KMFError::OK );
|
|
changed();
|
|
return m_err;
|
|
}
|
|
}
|
|
|
|
KMFError* IPTable::moveRuleToChain( IPTRule* rule, IPTChain *target_chain ) {
|
|
// kdDebug() << "KMFError* IPTable::moveRuleToChain(IPTRule* rule, IPTChain *target_chain )" << endl;
|
|
if ( rule == 0 ) {
|
|
m_err->setErrType( KMFError::FATAL );
|
|
const TQString& msg = i18n( "IPTable::moveRuleToChain(IPTRule* rule, IPTChain *target_chain"
|
|
"rule == 0. This is a bug." );
|
|
m_err->setErrMsg( msg );
|
|
return m_err;
|
|
}
|
|
if ( target_chain == 0 ) {
|
|
m_err->setErrType( KMFError::FATAL );
|
|
const TQString& msg = i18n( "IPTable::moveRuleToChain(IPTRule* rule, IPTChain *target_chain"
|
|
"target_chain == 0. This is a bug." );
|
|
m_err->setErrMsg( msg );
|
|
return m_err;
|
|
}
|
|
// kdDebug() << "Move Rule: " << rule->name() <<" from Chain: " << rule->chain() ->name() << "to chain" << target_chain->name() << endl;
|
|
|
|
IPTRule* new_rule = target_chain->addRule( i18n( "%1_Copy" ).arg( rule->name() ), m_err );
|
|
if ( m_err->errNum() == 0 ) {
|
|
rule->createRuleClone( new_rule );
|
|
IPTRule* ru = rule;
|
|
rule->chain()->delRule( ru );
|
|
}
|
|
return m_err;
|
|
}
|
|
|
|
KMFError* IPTable::copyRuleToChain( IPTRule* rule, IPTChain *target_chain ) {
|
|
// kdDebug() << "KMFError* IPTable::copyRuleToChain(IPTRule* rule, IPTChain *target_chain )" << endl;
|
|
if ( rule == 0 ) {
|
|
m_err->setErrType( KMFError::FATAL );
|
|
const TQString& msg = i18n( "IPTable::moveRuleToChain(IPTRule* rule, IPTChain *target_chain"
|
|
"rule == 0. This is a bug " );
|
|
m_err->setErrMsg( msg );
|
|
return m_err;
|
|
}
|
|
if ( target_chain == 0 ) {
|
|
m_err->setErrType( KMFError::FATAL );
|
|
const TQString& msg = i18n( "IPTable::moveRuleToChain(IPTRule* rule, IPTChain *target_chain"
|
|
"target_chain == 0. This is a bug " );
|
|
m_err->setErrMsg( msg );
|
|
return m_err;
|
|
}
|
|
// kdDebug() << "Copy Rule: " << rule->name() << " from Chain: " << rule->chain() ->name() << "to chain" << target_chain->name() << endl;
|
|
|
|
IPTRule* new_rule = target_chain->addRule( i18n( "%1_Copy" ).arg( rule->name() ), m_err );
|
|
if ( m_err->errNum() == 0 ) {
|
|
rule->createRuleClone( new_rule );
|
|
}
|
|
return m_err;
|
|
}
|
|
|
|
const TQDomDocument& IPTable::getDOMTree() {
|
|
// kdDebug() << "const TQString& IPTChain::getIDOMree( )" << endl;
|
|
TQDomDocument doc;
|
|
TQDomElement root = doc.createElement( XML::Table_Element );
|
|
NetfilterObject::saveUuid( root );
|
|
root.setAttribute( XML::Name_Attribute, name() );
|
|
root.setAttribute( XML::Description_Attribute, description() );
|
|
|
|
TQPtrListIterator<IPTChain> it ( m_chains );
|
|
IPTChain *chain = 0;
|
|
while ( ( chain = it.current() ) != 0 ) {
|
|
++it;
|
|
if ( chain ) {
|
|
root.appendChild( chain->getDOMTree( ) );
|
|
// kdDebug() << "Got XML for Rule: " << *chain->name() << endl;
|
|
} else {
|
|
kdDebug() << "Rule == 0"<< endl;
|
|
}
|
|
}
|
|
doc.appendChild( root );
|
|
return *( new TQDomDocument( doc ) );
|
|
}
|
|
|
|
void IPTable::loadXML( const TQDomDocument& doc, TQStringList& errors ) {
|
|
kdDebug() << "void IPTable::loadXML( const TQDomDocument& )" << endl;
|
|
TQDomElement root = doc.documentElement();
|
|
loadXML( root, errors );
|
|
}
|
|
void IPTable::loadXML( TQDomNode root, TQStringList& errors ) {
|
|
setName( name() );
|
|
NetfilterObject::loadUuid ( root, errors );
|
|
// TQDomElement root = doc.documentElement();
|
|
TQDomNode curr = root.firstChild();
|
|
TQPtrList<IPTChain> used_chains;
|
|
while ( !curr.isNull() ) {
|
|
// kdDebug() << "Parsing Node: " << curr.nodeName() << endl;
|
|
if ( curr.isElement() && curr.nodeName() == XML::Chain_Element ) {
|
|
TQString name = curr.toElement().attribute( XML::Name_Attribute );
|
|
TQString uuid = curr.toElement().attribute( XML::Uuid_Attribute );
|
|
TQUuid chain_uuid( uuid );
|
|
|
|
// kdDebug() << "IPTable: Start Parsing Chain: " << name << endl;
|
|
TQDomDocument chain_xml;
|
|
chain_xml.appendChild( curr.cloneNode(true) );
|
|
IPTChain* chain = 0;
|
|
chain = chainForUuid( chain_uuid );
|
|
if ( ! chain ) {
|
|
chain = chainForName( name );
|
|
if ( ! chain ) {
|
|
chain = addChain( name ,*( new TQString( "ACCEPT" ) ), false, m_err );
|
|
if ( m_err->errNum() != 0 ) {
|
|
kdDebug() << "ERROR: Couldn't create Chain: " << name << endl;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
chain->loadXML( chain_xml, errors );
|
|
used_chains.append( chain );
|
|
// kdDebug() << "IPTable: Finished Parsing Chain: " << name << endl;
|
|
}
|
|
curr = curr.nextSibling();
|
|
}
|
|
|
|
TQPtrListIterator<IPTChain> it ( m_chains );
|
|
while ( it.current() ) {
|
|
// kdDebug() << "IPTChain::xloadXML() cleanup loop." << endl;
|
|
IPTChain *chain = it.current();
|
|
TQPtrListIterator<IPTChain> it2 ( used_chains );
|
|
bool found = false;
|
|
while ( it2.current() ) {
|
|
IPTChain *chain2 = it2.current();
|
|
++it2;
|
|
if ( chain2 == chain )
|
|
found = true;
|
|
}
|
|
if ( ! found ) {
|
|
m_err = delChain( chain );
|
|
if ( m_err->errNum() != 0 )
|
|
++it;
|
|
} else {
|
|
++it;
|
|
}
|
|
}
|
|
changed();
|
|
}
|
|
|
|
}
|