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/kmfnethost.cpp

395 lines
12 KiB

//
// C++ Implementation: kmfnethost
//
// 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 "kmfnethost.h"
#include "kmftarget.h"
// TQt includes
#include <tqdom.h>
// KDE includes
#include <kdebug.h>
#include <tdelocale.h>
// Project includes
#include "kmfundoengine.h"
#include "kmfcheckinput.h"
#include "kmfprotocol.h"
#include "kmfprotocollibrary.h"
#include "kmfprotocolusage.h"
#include "kmfnetzone.h"
#include "kmfgenericdoc.h"
#include "kmferror.h"
#include "ipaddress.h"
#include "xmlnames.h"
#include <stdlib.h>
namespace KMF {
KMFNetHost::KMFNetHost( NetfilterObject *parent, const char* name, const TQString& hostName, KMFNetwork* net ) : KMFTarget( parent, name, hostName, net ) {
m_logIncoming = false;
m_logOutgoing = false;
m_guiName = i18n("New Host");
m_address = new IPAddress( 0,0,0,0 );
m_limitScale = "minute";
m_limitNum = -1;
m_protocols.setAutoDelete( false );
setName( hostName );
// m_object_type = NETHOST;
if ( KMFNetZone* zone = dynamic_cast<KMFNetZone*> ( parent ) ) {
m_zone = zone;
m_address->setAddress( m_zone->address()->toString() );
} else {
kdDebug() << "ERROR: KMFNetHost called with wrong Parent class." << endl;
}
}
//
KMFNetHost::~KMFNetHost() {
kdDebug() << "KMFNetHost::~KMFNetHost()" << endl;
clear();
}
int KMFNetHost::type() {
kdDebug() << "KMFNetHost::type()" << endl;
return NetfilterObject::NETHOST;
}
void KMFNetHost::clear() {
m_protocols.setAutoDelete( true );
m_protocols.clear();
m_protocols.setAutoDelete( false );
}
void KMFNetHost::setLogIncoming( bool onoff ) {
if ( onoff == m_logIncoming ) {
return;
}
m_logIncoming = onoff;
changed();
}
void KMFNetHost::setLogOutgoing( bool onoff ) {
if ( onoff == m_logOutgoing ) {
return;
}
m_logOutgoing = onoff;
changed();
}
void KMFNetHost::setLimit( int num, const TQString& scale ) {
if ( num < 1 ) {
m_limitNum = -1;
m_limitScale = "minute";
return;
}
m_limitNum = num;
m_limitScale = scale;
changed();
}
bool KMFNetHost::limit() const {
if ( m_limitNum > 0 )
return true;
return false;
}
int KMFNetHost::limitRate() const {
return m_limitNum;
}
const TQString& KMFNetHost::limitScale() const {
return m_limitScale;
}
TQPtrList<KMFProtocolUsage>& KMFNetHost::protocols() const {
TQPtrList<KMFProtocolUsage>* ret_val = new TQPtrList<KMFProtocolUsage>;
*ret_val = m_protocols;
return *ret_val;
}
KMFProtocolUsage* KMFNetHost::findProtocolUsageByProtocolUuid( const TQUuid& uuid ) const {
kdDebug() << "KMFProtocol* KMFNetHost::findProtocolUsageByProtocolUuid( const TQUuid& " << uuid.toString() << " ) const" << endl;
if ( (new TQUuid(uuid))->isNull() ) {
exit(1);
}
TQPtrListIterator<KMFProtocolUsage> it(m_protocols);
while ( it.current() ) {
KMFProtocolUsage *p = it.current();
++it;
if ( p->protocol()->uuid() == uuid ) {
// kdDebug() << "Found Protocol: " << name << endl;
return p;
}
}
return 0;
}
KMFProtocolUsage* KMFNetHost::addProtocolUsage( const TQUuid& protocolUuid, const TQDomDocument& xml ) {
// kdDebug() << "KMFNetHost* KMFNetZone::addProtocolUsage( const TQUuid& " << protocolUuid.toString() << ", const TQDomDocument& xml )" << endl;
if ( protocolUuid.isNull() ) {
kdDebug() << "ERROR: protocolUuid.isNull()" << endl;
exit(1);
}
KMFProtocolUsage* old = findProtocolUsageByProtocolUuid( protocolUuid );
if ( old ) {
kdDebug() << "WARNING: Ignoreing duplicate protocol entry in zone" << endl;
return old;
}
KMFProtocol* prot = KMFProtocolLibrary::instance()->findProtocolByUuid( protocolUuid );
if ( ! prot ) {
kdDebug() << "ERROR: No Protocol Found By uuid: " << protocolUuid << endl;
return 0;
}
KMFProtocolUsage* new_protocol = prot->createUsage();
// FIXME: Check For Error
TQStringList *errors = new TQStringList();
new_protocol->loadXML( xml, *errors );
if ( ! new_protocol->validUsage() ) {
kdDebug() << "WARNING: ProtocolUsage parsed from: " << xml.toString() << " is not Valid! Skippin Usage." << endl;
return 0;
}
new_protocol->setProtocol( prot );
m_protocols.append( new_protocol );
disconnect( new_protocol, TQ_SIGNAL( destroyed( TQObject* ) ),
this, TQ_SLOT( slotOnProtocolUsageDeleted( TQObject* ) ) );
connect( new_protocol, TQ_SIGNAL( destroyed( TQObject* ) ),
this, TQ_SLOT( slotOnProtocolUsageDeleted( TQObject* ) ) );
changed();
return new_protocol;
}
void KMFNetHost::delProtocolUsage( KMFProtocolUsage* prot, bool destructive ){
// kdDebug() << "void KMFNetHost::delProtocol( KMFProtocol* prot )" << endl;
TQPtrListIterator<KMFProtocolUsage> it( m_protocols );
bool deleted = false;
while ( it.current() ) {
KMFProtocolUsage *p = it.current();
kdDebug() << "Comparing protocol: " << prot->uuid() << " with protocol: " << p->uuid() << endl;
if ( p->name() == prot->name() ) {
kdDebug() << "Delete protocol: " << prot->uuid() << " from host: " << name() << endl;
m_protocols.remove( p );
if ( destructive ) {
p->deleteLater();
}
deleted = true;
}
++it;
}
if ( ! deleted ) {
kdDebug() << "WARNING: Couldn't delete protocol: " << prot->name() << " from host: " << name() << endl;
}
changed();
}
void KMFNetHost::slotOnProtocolUsageDeleted( TQObject* prot ) {
kdDebug() << "KMFNetHost::slotOnProtocolUsageDeleted... Host name: " << this->name() << endl;
TQPtrListIterator<KMFProtocolUsage> it( m_protocols );
while ( it.current() ) {
KMFProtocolUsage * p = it.current();
++it;
if ( p == prot ) {
kdDebug() << "Deleting Protocol" << endl;
m_protocols.remove( p );
p->deleteLater();
changed();
return;
}
}
}
bool KMFNetHost::protocolInherited( const TQUuid& uuid ) const {
// kdDebug() << "bool KMFNetHost::protocolInherited() const" << endl;
if ( ! m_zone )
return false;
if ( uuid.isNull() ) {
kdDebug() << "ERROR: KMFNetHost::protocolInherited(): uuid.isNull() == true" << endl;
exit(1);
}
TQPtrListIterator<KMFProtocolUsage> it( m_zone->protocols() );
while ( it.current() ) {
KMFProtocolUsage *p = it.current();
++it;
if ( p->protocol()->uuid() == uuid ) {
kdDebug() << "Found Inherited Protocol: " << p->protocol()->name() << endl;
return true;
}
}
return m_zone->protocolInherited( uuid );
}
const TQDomDocument& KMFNetHost::getDOMTree() {
kdDebug() << "const TQDomDocument& KMFNetHost::getDOMTree() " << endl;
TQDomDocument doc;
TQDomElement root = doc.createElement( XML::NetHost_Element );
NetfilterObject::saveUuid( root );
root.setAttribute( XML::Name_Attribute, name() );
root.setAttribute( XML::GUIName_Attribute, m_guiName );
root.setAttribute( XML::Description_Attribute, description() );
root.setAttribute( XML::Address_Attribute, m_address->toString() );
if ( logIncoming() ) {
root.setAttribute( XML::LogIncoming_Attribute, XML::BoolOn_Value );
} else {
root.setAttribute( XML::LogIncoming_Attribute, XML::BoolOff_Value );
}
if ( logOutgoing() ) {
root.setAttribute( XML::LogOutgoing_Attribute, XML::BoolOn_Value );
} else {
root.setAttribute( XML::LogOutgoing_Attribute, XML::BoolOff_Value );
}
root.setAttribute( XML::LimitRate_Attribute, limitRate() );
root.setAttribute( XML::LimitScale_Attribute, limitScale() );
TQPtrListIterator<KMFProtocolUsage> it2 ( m_protocols );
while ( it2.current() ) {
root.appendChild( it2.current()->getDOMTree( ) );
++it2;
}
doc.appendChild( root );
return *( new TQDomDocument( doc ) );
}
void KMFNetHost::loadXML( const TQDomDocument& doc, TQStringList& errors ) {
// kdDebug() << "void KMFNetHost::loadXML( const TQDomDocument& )" << endl;
TQDomElement root = doc.documentElement();
loadXML( root, errors );
}
void KMFNetHost::loadXML( TQDomNode root, TQStringList& errors ) {
kdDebug() << "void KMFNetHost::loadXML( TQDomNode root )" << endl;
//TQDomElement root = doc.documentElement();
NetfilterObject::loadUuid( root, errors );
TQString name = "";
TQString guiName = "";
TQString desc = "";
TQString address = "";
TQString logIn = "";
TQString logOut = "";
TQString limitRate = "";
TQString limitScale = "";
name = root.toElement().attribute( XML::Name_Attribute );
guiName = root.toElement().attribute( XML::GUIName_Attribute );
desc = root.toElement().attribute( XML::Description_Attribute );
address = root.toElement().attribute( XML::Address_Attribute );
logIn = root.toElement().attribute( XML::LogIncoming_Attribute );
logOut = root.toElement().attribute( XML::LogOutgoing_Attribute );
limitRate = root.toElement().attribute( XML::LimitRate_Attribute );
limitScale = root.toElement().attribute( XML::LimitScale_Attribute );
if ( logIn == XML::BoolOn_Value ) {
m_logIncoming = true;
} else {
m_logIncoming = false;
}
if ( logOut == XML::BoolOn_Value ) {
m_logOutgoing = true;
} else {
m_logOutgoing = false;
}
bool ok;
int lRate = limitRate.toInt( &ok );
if ( ok ) {
setLimit( lRate, *( new TQString( limitScale ) ) );
}
setDescription( *( new TQString( desc ) ) );
// setName( *( new TQString( name ) ) );
setGuiName( *( new TQString( guiName ) ) );
this->address()->setAddress( address );
TQValueList< KMFProtocolUsage* > xmlDefinedProtocols;
TQDomNode curr = root.firstChild();
while ( !curr.isNull() ) {
if ( curr.isElement() && ( curr.nodeName() == XML::Protocol_Element ) ) {
// FIXME: Remove later
// keep for compatibility
TQString name = curr.toElement().attribute( XML::Name_Attribute );
TQDomDocument protocol_doc;
protocol_doc.appendChild( curr.cloneNode(true) );
KMFProtocol *protocol = KMFProtocolLibrary::instance()->findProtocolByName( name );
if ( ! protocol ) {
KMFUndoEngine::instance()->log( i18n("No Protocol Found by name: %1").arg( name ), KMFError::OK, this );
continue;
}
KMFProtocolUsage* pu = addProtocolUsage( protocol->uuid(), protocol_doc );
if ( pu ) {
xmlDefinedProtocols.append( pu );
}
}
if ( curr.isElement() && ( curr.nodeName() == XML::ProtocolUsage_Element ) ) {
TQString protocolUuid = curr.toElement().attribute( XML::ProtocolUuid_Attribute );
TQDomDocument protocol_doc;
protocol_doc.appendChild( curr.cloneNode(true) );
KMFProtocolUsage* pu = addProtocolUsage( protocolUuid , protocol_doc );
if ( pu ) {
xmlDefinedProtocols.append( pu );
}
}
curr = curr.nextSibling();
}
{
TQPtrList< KMFProtocolUsage >& allprotocols = protocols();
TQPtrListIterator< KMFProtocolUsage > itAllProtocols( allprotocols );
while( itAllProtocols.current() ) {
KMFProtocolUsage *oldProtocolUsage = itAllProtocols.current();
++itAllProtocols;
bool found = false;
TQValueList< KMFProtocolUsage* >::iterator itProtocols;
for( itProtocols = xmlDefinedProtocols.begin(); itProtocols != xmlDefinedProtocols.end() && ! found; ++itProtocols ) {
KMFProtocolUsage* pu = *itProtocols;
if ( pu == oldProtocolUsage ) {
found = true;
}
}
if ( ! found ) {
KMFUndoEngine::instance()->log( i18n("Removing unused oldProtocolUsage: %1").arg( oldProtocolUsage->name() ), KMFError::OK, this );
delProtocolUsage( oldProtocolUsage, true );
}
}
}
changed();
}
}