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.
kmyfirewall/kmyfirewall/core/kmfiptdoc.cpp

488 lines
14 KiB

//
// C++ Implementation: kmfiptdoc
//
// Description:
//
//
// Author: Christian Hubinger <chubinger@irrsinnig.org>, (C) 2003
//
// Copyright: See COPYING file that comes with this distribution
//
//
/***************************************************************************
* *
* 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 "kmfiptdoc.h"
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
// StdLib includes
#include <iostream>
#include <unistd.h>
#include <sys/stat.h>
// TQt includes
#include <tqtextstream.h>
#include <tqfile.h>
#include <tqxml.h>
#include <tqregexp.h>
#include <tqptrlist.h>
#include <tqmessagebox.h>
#include <tqstringlist.h>
#include <tqvbox.h>
#include <tqlabel.h>
// KDE includes
#include <kdebug.h>
#include <kstandarddirs.h>
#include <tdefiledialog.h>
#include <kurl.h>
#include <tqfiledialog.h>
#include <tdeio/job.h>
#include <tdeio/netaccess.h>
#include <tdelocale.h>
#include <kprocess.h>
#include <tdeapplication.h>
#include <tdeconfig.h>
#include <tdemessagebox.h>
#include <tdetempfile.h>
#include <ktrader.h>
#include <klibloader.h>
// My includes
#include "../version.h"
#include "kmfcompilerinterface.h"
#include "kmfplugin.h"
#include "kmfdoc.h"
#include "iptchain.h"
#include "iptrule.h"
#include "iptable.h"
#include "netfilterobject.h"
#include "kmferror.h"
#include "kmferrorhandler.h"
#include "kmfpluginfactory.h"
#include "kmfconfig.h"
#include "kmftarget.h"
#include "kmfnetwork.h"
#include "kmfundoengine.h"
#include "xmlnames.h"
namespace KMF {
KMFIPTDoc::KMFIPTDoc( NetfilterObject *parent, const char *name, KMFTarget* target ) : KMFDoc( parent, name ), KMFRulesetDoc( target ) {
initDoc();
}
KMFIPTDoc::~KMFIPTDoc() {
kdDebug() << "Callong KMFIPTDoc::~KMFIPTDoc()" << endl;
m_ipt_filter->deleteLater();
m_ipt_nat->deleteLater();;
m_ipt_mangle->deleteLater();;
// error handler
delete m_err;
m_err = 0;
}
int KMFIPTDoc::type() {
// kdDebug() << "IPTRule::type()" << endl;
return NetfilterObject::IPTABLES_RULESET;
}
void KMFIPTDoc::initDoc() {
// kdDebug() << "\n\nvoid KMFIPTDoc::initKMFIPTDoc()" << endl;
// registerRuleOptions();
m_err_handler = new KMFErrorHandler( "KMFIPTDoc" );
m_err = new KMFError();
m_url.setFileName( i18n( "Untitled" ) );
m_use_filter = true;
m_use_nat = true;
m_use_mangle = true;
m_use_ipfwd = true;
m_use_rp_filter = false;
m_use_martians = false;
m_use_syn_cookies = true;
m_use_modules = true;
// is_saved = false;
m_ipt_filter = new IPTable( this, Constants::FilterTable_Name.latin1(),
Constants::FilterTable_Name.latin1() );
m_ipt_filter->settupDefaultChains();
m_ipt_nat = new IPTable( this, Constants::NatTable_Name.latin1(), Constants::NatTable_Name );
m_ipt_nat->settupDefaultChains();
m_ipt_mangle = new IPTable( this, Constants::MangleTable_Name.latin1(), Constants::MangleTable_Name );
m_ipt_mangle->settupDefaultChains();
}
void KMFIPTDoc::clear() {
m_url.setFileName( i18n( "Untitled" ) );
m_use_filter = true;
m_use_nat = true;
m_use_mangle = true;
m_use_ipfwd = true;
m_use_rp_filter = false;
m_use_martians = false;
m_use_syn_cookies = true;
m_use_modules = true;
// m_changed_objects.clear();
// is_saved = false;
m_ipt_filter->reset();
m_ipt_nat->reset();
m_ipt_mangle->reset();
setName( i18n("Unamed Ruleset") );
setDescription( i18n("No description available") );
resetUrl();
}
const TQString& KMFIPTDoc::getFileDialogFilter() {
return *( new TQString("*.kmfrs|KMyFirewall IPTables Ruleset(*.kmfrs)") );
}
void KMFIPTDoc::setUseFilter( bool on ) {
if ( m_use_filter != on ) {
m_use_filter = on;
changed();
}
}
void KMFIPTDoc::setUseNat( bool on ) {
if ( m_use_nat != on ) {
m_use_nat = on;
changed();
}
}
void KMFIPTDoc::setUseMangle( bool on ) {
if ( m_use_mangle != on ) {
m_use_mangle = on;
changed();
}
}
void KMFIPTDoc::setUseIPFwd( bool on ) {
if ( m_use_ipfwd != on ) {
m_use_ipfwd = on;
changed();
}
}
void KMFIPTDoc::setUseRPFilter( bool on ) {
if ( m_use_rp_filter != on ) {
m_use_rp_filter = on;
changed();
}
}
void KMFIPTDoc::setUseMartians( bool on ) {
if ( m_use_martians != on ) {
m_use_martians = on;
changed();
}
}
void KMFIPTDoc::setUseSynCookies( bool on ) {
if ( m_use_syn_cookies != on ) {
m_use_syn_cookies = on;
changed();
}
}
void KMFIPTDoc::setUseModules( bool on ) {
if ( m_use_modules != on ) {
m_use_modules = on;
changed();
}
}
bool KMFIPTDoc::isEmpty() {
if ( m_ipt_filter->chains().isEmpty() && m_ipt_nat->chains().isEmpty() && m_ipt_mangle->chains().isEmpty() ) {
return true;
} else {
return false;
}
return false;
}
const TQDomDocument& KMFIPTDoc::getDOMTree() {
// kdDebug() << "const TQDomDocument& KMFIPTDoc::getDOMTree()" << endl;
TQDomDocument doc( "kmyfirewall-ruleset" );
TQDomElement root = doc.createElement( XML::IPTDoc_DocumentElement );
NetfilterObject::saveUuid( root );
root.setAttribute( XML::Version_Attribute, KMYFIREWALL_VERSION );
root.setAttribute( XML::MinVersion_Attribute, "1.0.0" );
root.setAttribute( XML::MaxVersion_Attribute, "~" );
TQDomElement abstract = doc.createElement( XML::Abstract_Element );
root.appendChild( abstract );
if ( useFilter() ) {
abstract.setAttribute( XML::UseFilter_Attribute, XML::Yes_Value );
} else {
abstract.setAttribute( XML::UseFilter_Attribute, XML::No_Value );
}
if ( useNat() ) {
abstract.setAttribute( XML::Use_Nat_Attribute, XML::Yes_Value );
} else {
abstract.setAttribute( XML::Use_Nat_Attribute, XML::No_Value );
}
if ( useMangle() ) {
abstract.setAttribute( XML::UseMangle_Attribute, XML::Yes_Value );
} else {
abstract.setAttribute( XML::UseMangle_Attribute, XML::No_Value );
}
if ( useModules() ) {
abstract.setAttribute( XML::UseModules_Attribute, XML::Yes_Value );
} else {
abstract.setAttribute( XML::UseModules_Attribute, XML::No_Value );
}
if ( useRPFilter() ) {
abstract.setAttribute( XML::UseRpFilter_Attribute, XML::Yes_Value );
} else {
abstract.setAttribute( XML::UseRpFilter_Attribute, XML::No_Value );
}
if ( useIPFwd() ) {
abstract.setAttribute( XML::UseIPFwd_Attribute, XML::Yes_Value );
} else {
abstract.setAttribute( XML::UseIPFwd_Attribute, XML::No_Value );
}
if ( useSynCookies() ) {
abstract.setAttribute( XML::UseSynCookies_Attribute, XML::Yes_Value );
} else {
abstract.setAttribute( XML::UseSynCookies_Attribute, XML::No_Value );
}
if ( useMartians() ) {
abstract.setAttribute( XML::UseMartians_Attribute, XML::Yes_Value );
} else {
abstract.setAttribute( XML::UseMartians_Attribute, XML::No_Value );
}
abstract.setAttribute( XML::Description_Attribute, description() );
abstract.setAttribute( XML::Name_Attribute, name() );
root.appendChild( m_ipt_filter->getDOMTree( ) );
root.appendChild( m_ipt_nat->getDOMTree( ) );
root.appendChild( m_ipt_mangle->getDOMTree( ) );
doc.appendChild( root );
return *( new TQDomDocument( doc ) );
}
void KMFIPTDoc::loadXML( const TQDomDocument& doc, TQStringList& errors ) {
kdDebug() << "void KMFIPTDoc::loadXML( const TQDomDocument& )" << endl;
TQDomElement root = doc.documentElement();
if ( root.nodeName() != XML::IPTDoc_DocumentElement ) {
kdDebug() << "!!! ERROR: Wrong XML format " << root.nodeName() << " found !!!" << endl;
errors.append( KMFError::getAsString( KMFError::FATAL, i18n("Wrong XML format <b>%1</b> found! Expected kmfrs").arg( root.nodeName() ) ) );
return;
}
loadXML( root, errors );
}
void KMFIPTDoc::loadXML( TQDomNode root, TQStringList& errors ) {
kdDebug() << "void KMFIPTDoc::loadXML( TQDomNode root, TQStringList& errors )" << endl;
if ( root.nodeName() != XML::IPTDoc_DocumentElement ) {
kdDebug() << "!!! ERROR: Wrong XML format " << root.nodeName() << " found !!!" << endl;
errors.append( KMFError::getAsString( KMFError::FATAL, i18n("Wrong XML format <b>%1</b> found! Expected kmfrs").arg( root.nodeName() ) ) );
return;
}
NetfilterObject::loadUuid( root, errors );
TQDomNode curr = root.firstChild();
while ( !curr.isNull() ) {
kdDebug() << "Parsing Node: " << curr.nodeName() << endl;
if ( curr.isElement() && curr.nodeName() == XML::Table_Element ) {
TQString name = curr.toElement().attribute( XML::Name_Attribute );
kdDebug() << "KMFIPTDoc: Start Parsing Table: " << name << endl;
TQDomDocument table;
table.appendChild( curr.cloneNode( true ) );
if ( name == Constants::FilterTable_Name ) {
m_ipt_filter->loadXML( table, errors );
} else if ( name == Constants::NatTable_Name ) {
m_ipt_nat->loadXML( table, errors );
} else if ( name == Constants::MangleTable_Name ) {
m_ipt_mangle->loadXML( table, errors );
}
kdDebug() << "KMFIPTDoc: Finished Parsing Table: " << name << endl;
} else if ( curr.isElement() && curr.nodeName() == XML::Abstract_Element ) {
kdDebug() << "KMFIPTDoc: Start Parsing Abstract" << endl;
TQString filter;
TQString nat;
TQString mangle;
TQString martians;
TQString ipfwd;
TQString syncookies;
TQString rpfilter;
TQString modules;
TQString description = "";
TQString name = "";
filter = curr.toElement().attribute( XML::UseFilter_Attribute );
nat = curr.toElement().attribute( XML::Use_Nat_Attribute );
mangle = curr.toElement().attribute( XML::UseMangle_Attribute );
martians = curr.toElement().attribute( XML::UseMartians_Attribute );
ipfwd = curr.toElement().attribute( XML::UseIPFwd_Attribute );
syncookies = curr.toElement().attribute( XML::UseSynCookies_Attribute );
rpfilter = curr.toElement().attribute( XML::UseRpFilter_Attribute );
modules = curr.toElement().attribute( XML::UseModules_Attribute );
description += curr.toElement().attribute( XML::Description_Attribute );
if ( ! description.isNull() )
setDescription( *( new TQString( description ) ) );
name = curr.toElement().attribute( XML::Name_Attribute );
if ( ! name.isNull() )
setName( *( new TQString( name ) ) );
if ( filter == XML::Yes_Value )
m_use_filter = true;
else
m_use_filter = false;
if ( nat == XML::Yes_Value )
m_use_nat = true;
else
m_use_nat = false;
if ( mangle == XML::Yes_Value )
m_use_mangle = true;
else
m_use_mangle = false;
if ( martians == XML::Yes_Value )
m_use_martians = true;
else
m_use_martians = false;
if ( ipfwd == XML::Yes_Value )
m_use_ipfwd = true;
else
m_use_ipfwd = false;
if ( syncookies == XML::Yes_Value )
m_use_syn_cookies = true;
else
m_use_syn_cookies = false;
if ( rpfilter == XML::Yes_Value )
m_use_rp_filter = true;
else
m_use_rp_filter = false;
if ( modules == XML::Yes_Value )
m_use_modules = true;
else
m_use_modules = false;
kdDebug() << "KMFIPTDoc: Finished Parsing Abstract" << endl;
}
curr = curr.nextSibling();
}
changed();
}
IPTable* KMFIPTDoc::table( const TQString& table ) {
if ( table == Constants::FilterTable_Name )
return m_ipt_filter;
if ( table == Constants::NatTable_Name )
return m_ipt_nat;
if ( table == Constants::MangleTable_Name )
return m_ipt_mangle;
return 0;
}
const TQString& KMFIPTDoc::compile() {
KMFCompilerInterface* compiler = target()->compiler();
if ( ! compiler ) {
return *( new TQString("ERROR") );
}
return compiler->compile( this );
}
void KMFIPTDoc::parseDocument( const KURL& url, TQStringList& errors ) {
// kdDebug() << "KMFIPTDoc::parseDocument()" << endl;
TQString xmlfile;
if ( ! TDEIO::NetAccess::download( url, xmlfile, TDEApplication::kApplication()->mainWidget() ) ) {
clear();
m_url.setFileName( i18n( "Untitled" ) );
return;
// return this;
}
if ( !xmlfile.isEmpty() ) {
// kdDebug() << "Found xmlfile: " << xmlfile << endl;
// delete old chainsets if there
if ( !m_ipt_filter->chains().isEmpty() )
m_ipt_filter->reset();
if ( !m_ipt_nat->chains().isEmpty() )
m_ipt_nat->reset();
if ( !m_ipt_mangle->chains().isEmpty() )
m_ipt_mangle->reset();
clear();
TQFile kmfrsFile( xmlfile );
TQDomDocument domTree;
if ( !kmfrsFile.open( IO_ReadOnly ) ) {
return;
// return 0;
}
if ( !domTree.setContent( &kmfrsFile ) ) {
kmfrsFile.close();
return;
// return 0;
}
kmfrsFile.close();
kdDebug() << "############ Start Parsing ############" << endl;
loadXML( domTree, errors );
kdDebug() << "########## Finished Parsing ###########" << endl;
// setUrl( url );
m_url = url;
emit documentChanged();
TDEIO::NetAccess::removeTempFile( xmlfile );
return;
// return this;
}
TDEIO::NetAccess::removeTempFile( xmlfile );
// return this;
}
void KMFIPTDoc::registerRuleOptions() {
kdDebug() << "KMFIPTDoc::registerRuleOptions()" << endl;
TDEStandardDirs std_dir;
TQStringList files = std_dir.findAllResources(
"data", "kmyfirewall/ruleoptions/kmfruleoption*.xml", false, true );
for ( TQStringList::Iterator it = files.begin(); it != files.end(); ++it ) {
kdDebug() << "Found Option XML File: " << *it << endl;
TQString xmlfile = *it;
TQFile document( xmlfile );
TQDomDocument domTree;
if ( !document.open( IO_ReadOnly ) ) {
kdDebug() << "ERROR: Can't read XML ruole option definition" << endl;
return;
}
if ( !domTree.setContent( &document ) ) {
kdDebug() << "ERROR: XML corrupted in file: " << xmlfile << endl;
document.close();
return;
}
document.close();
kdDebug() << "############ Start Parsing ############" << endl;
IPTRuleOption::readRuleOptionDefinition( domTree );
kdDebug() << "########## Finished Parsing ###########" << endl;
}
}
}