![]() | Rule- option/targetoptin Plugins (IPTables interface only) |
Prev | Developer's Guide to KMyFirewall | Next |
As the iptables command utility is really fast developing and every few week new options are added, all ruleoption handling is outsourced to small easy to write plugins.
The underlieing document format is designed flexible enougth to allow the implementaiton of any command option iptables knows (or will know, if i didn't forget anything).
The rule creation engine can be extend by registering new option/targetoption types defined in small XML files that are parsed at startup. And the editor GUI can embeed the edit widgets needed to configure the ruleoption.
A XML file named p.e. kmfruleoption_mac_option.xml
A desktop file p.e. kmfruleoptionedit_mac.desktop that registeres the plugin within the KDE services framework.
An KParts Plugin component/class that derives form either KMFRuleOptionEditInterface or KMFRuleTargetOptionEditInterface named p.e. KMFRuleOptionEditMAC
A Class deriving from QWidget that may be loaded into the editor view when editing that option.
Most likely you'll use QTDesigner to design the GUI. If you do this you need to inherit from the generated class.
The xml file gets loaded during application startup and registers the specified rule option in the engine. Have a look at some of the other XML files installed in $KDE-PREFIX/share/apps/kmyfirewall/ruleoptions for some more example of how to define the needed options.
<!DOCTYPE kmyfirewall-kmfruleoptiondefinition> <ruleoptiondefinitionset> <ruleoptiondefinition name="mac_opt" guiName="MAC Address"> <option guiName="" command="--match mac" /> <option guiName="MAC:" command="--mac-source" /> </ruleoptiondefinition> </ruleoptiondefinitionset>
This file is installed into the services directory and makes the plugin available for the KDE plugin framework
The important thing here is that you set Type=Service and the right SeviceType. The application only searches for plugins with SeviceType=KMyFirewall/RuleOptionEdit or SeviceType=KMyFirewall/RuleTargetOptionEdit.
The line X-KDE-Library=libkmfruleoptionedit_mac lets the KDE plugin framework know which library defines the functionality.
[Desktop Entry] Encoding=UTF-8 Type=Service Name=KMyFirewall MAC option edit Name[da]=KMyFirewall MAC redigeringstilvalg Comment=Plugin for edition MAC address based iptables rule options Comment[da]=Plugin ril at redigere MAC adressebaserede regeltilvalg for iptables X-KDE-Library=libkmfruleoptionedit_mac ServiceTypes=KMyFirewall/RuleOptionEdit
Make shure that you add the option -module $(KDE_PLUGIN) to the <library_name>_LDFLAGS. Otherwise the plugin can not be loaded at runtime.
INCLUDES = -I../kmfwidgets -I../../ipteditor -I$(srcdir)/../interfaces $(all_includes) METASOURCES = AUTO kde_module_LTLIBRARIES = libkmfruleoptionedit_mac.la libkmfruleoptionedit_mac_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries) libkmfruleoptionedit_mac_la_LIBADD = ../../core/libkmfcore.la ../../interfaces/libkmfinterfaces.la $(LIB_KPARTS) noinst_HEADERS = kmfruleoptioneditmac.h kmfruleeditmac.h libkmfruleoptionedit_mac_la_SOURCES = kmfruleoptioneditmac.cpp kmfruleeditmac.cpp kmyfirewallruleeditormac.ui partdesktopdir = $(kde_servicesdir) partdesktop_DATA = kmfruleoptionedit_mac.desktop install-data-local: $(mkinstalldirs) $(DESTDIR)$(kde_datadir)/kmyfirewall/ruleoptions/ $(INSTALL_DATA) $(srcdir)/kmfruleoption_mac_option.xml $(DESTDIR)$(kde_datadir)/kmyfirewall/ruleoptions/kmfruleoption_mac_option.xml uninstall-local: -rm -f $(DESTDIR)$(kde_datadir)/kmyfirewall/ruleoptions/kmfruleoption_mac_option.xml
This class defines the plugin that will be loaded at application startup.
kmfruleoptioneditmac.h
/*************************************************************************** Copyright (C) 2004 Christian Hubinger ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ // Author: Christian Hubinger <chubinger@gmail.com>, (C) 2004 #ifndef KMFRULEOPTIONEDITMAC_H #define KMFRULEOPTIONEDITMAC_H #include "../../interfaces/kmfruleoptioneditinterface.h" // KDE includes #include <kparts/part.h> #include <kparts/plugin.h> #include <kparts/factory.h> #include <kxmlgui.h> #include <qstring.h> #include <qptrlist.h> class IPTRule; class KMFRuleEditMac; /** @author Christian Hubinger */ class KMFRuleOptionEditMAC : public KMFRuleOptionEditInterface { Q_OBJECT public: KMFRuleOptionEditMAC(QObject *parent = 0, const char *name = 0); ~KMFRuleOptionEditMAC(); void loadRule( IPTRule* rule ); QWidget* editWidget(); const QString& optionEditName() const; const QString& description() const; private slots: void slotAddRuleOption(QString*, QPtrList< QString >* ); void slotAddTargetOption(QString*, QPtrList< QString >* ); void slotShowOverview(); private: KMFRuleEditMac *m_edit; IPTRule *m_rule; }; class KInstance; class KMFRuleOptionEditMACFactory : public KLibFactory { Q_OBJECT public: KMFRuleOptionEditMACFactory( QObject *parent = 0, const char *name = 0 ); virtual ~KMFRuleOptionEditMACFactory() { }; virtual QObject* createObject( QObject* parent = 0, const char* pname = 0, const char* name = "QObject", const QStringList &args = QStringList() ); };
kmfruleoptioneditmac.cpp
/*************************************************************************** * * * 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 "kmfruleoptioneditmac.h" // QT includes #include <qstring.h> // KDE includes #include <kdebug.h> #include <klocale.h> // Project includes #include "../../core/iptrule.h" #include "../../interfaces/kmfruleeditinterface.h" #include "kmfruleeditmac.h" // Constructor get out plugin into a valid state KMFRuleOptionEditMAC::KMFRuleOptionEditMAC(QObject *parent, const char *name) : KMFRuleOptionEditInterface(parent, name) { // Initialise the editor class m_edit = new KMFRuleEditMac( 0 , "Edit", 0 ); // hide it for now m_edit->hide(); // Connect the Signals for the editor class to our slots passing them to the app connect( m_edit,SIGNAL(sigAddRuleOpt(QString*, QPtrList< QString >* ) ), this,SLOT( slotAddRuleOption(QString*, QPtrList< QString >* ) ) ); // //connect( m_edit,SIGNAL(sigAddTargetOpt(QString*, QPtrList< QString >* ) ), // this,SLOT( slotAddTargetOption(QString*, QPtrList< QString >* ) ) ); connect( m_edit,SIGNAL(sigHideMe() ), this,SLOT( slotShowOverview() ) ); } KMFRuleOptionEditMAC::~KMFRuleOptionEditMAC() {} // Slot to pass the Signals to the app void KMFRuleOptionEditMAC::slotAddRuleOption(QString* name, QPtrList< QString >* values ) { if ( KMFRuleEditInterface* ruleedit = dynamic_cast<KMFRuleEditInterface*> ( parent() ) ) { ruleedit->addRuleOption( name, values ); } else { kdDebug() << "KMFRuleOptionEditMAC::slotAddRuleOption(): parent() not of type KMFRuleEditInterface" << endl; } } void KMFRuleOptionEditMAC::slotAddTargetOption(QString* name, QPtrList< QString >* values ) { if ( KMFRuleEditInterface* ruleedit = dynamic_cast<KMFRuleEditInterface*> ( parent() ) ) { ruleedit->addRuleTargetOption( name, values ); } else { kdDebug() << "KMFRuleOptionEditMAC::slotAddTargetOption(): parent() not of type KMFRuleEditInterface" << endl; } } // Make the editor hide the plugin widget void KMFRuleOptionEditMAC::slotShowOverview() { if ( KMFRuleEditInterface* ruleedit = dynamic_cast<KMFRuleEditInterface*> ( parent() ) ) { ruleedit->showOverview(); } else { kdDebug() << "KMFRuleOptionEditMAC::slotShowOverview(): parent() not of type KMFRuleEditInterface" << endl; } } // Get info for GUI about the plugin const QString& KMFRuleOptionEditMAC::optionEditName() const { return *( new QString( i18n("MAC Option") ) ); } const QString& KMFRuleOptionEditMAC::description() const { return *( new QString( i18n("This plugin manages the MAC address based options of iptables.") ) ); } // We must implement this as it is called from the underliening rule editor void KMFRuleOptionEditMAC::loadRule( IPTRule* rule ) { if ( !rule ) { kdDebug() << "KMFRuleOptionEditMAC::loadRule( IPTRule* rule ) - rule == 0" <<endl; return; } m_edit->loadRule( rule ); m_rule = rule; } // return a pointer to our editor widget QWidget* KMFRuleOptionEditMAC::editWidget() { if ( ! m_edit ) { kdDebug() << "KMFRuleOptionEditMAC::editWidget() - m_edit == 0" << endl; return 0; } return m_edit; } // It's usually safe to leave the factory code alone.. with the // notable exception of the KAboutData data #include <kaboutdata.h> #include <klocale.h> // KInstance* KMFRuleOptionEditMACFactory::s_instance = 0L; // KAboutData* KMFRuleOptionEditMACFactory::s_about = 0L; KMFRuleOptionEditMACFactory::KMFRuleOptionEditMACFactory( QObject* parent, const char* name ) : KLibFactory( parent, name ) { } QObject* KMFRuleOptionEditMACFactory::createObject( QObject* parent, const char* name, const char*, const QStringList & ) { QObject * obj = new KMFRuleOptionEditMAC( parent, name ); emit objectCreated( obj ); return obj; } extern "C" { void* init_libkmfruleoptionedit_mac() { return new KMFRuleOptionEditMACFactory; } } #include "kmfruleoptioneditmac.moc"
This class defines a widget that can configure the specific rule option.
kmfruleeditmac.h
/*************************************************************************** * * * 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. * * * ***************************************************************************/ /* Author: Christian Hubinger <chubinger@gmail.com>, (C) 2001-2004 */ #ifndef KMFRULEEDITMAC_H #define KMFRULEEDITMAC_H #include "kmyfirewallruleeditormac.h" #include <qvariant.h> #include <qdialog.h> #include <qptrlist.h> class IPTRule; class KMFErrorHandler; class KMFCheckInput; class KMFError; class KMFRuleEditMac : public KMyFirewallRuleEditorMac { Q_OBJECT public: KMFRuleEditMac( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); ~KMFRuleEditMac(); void loadRule( IPTRule* ); public slots: void accept(); void slotHelp(); void reject(); protected: bool event( QEvent* ); private: KMFCheckInput *m_check_input; KMFErrorHandler *m_err_handler; KMFError *m_err; IPTRule* m_rule; signals: void sigAddRuleOpt( QString*, QPtrList<QString>* ); void sigHideMe(); }; #endif // KMFRULEEDITMAC_H
kmfruleeditmac.cpp
/*************************************************************************** * * * 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. * * * ***************************************************************************/ /* Author: Christian Hubinger <chubinger@gmail.com>, (C) 2001-2004 */ #include "kmfruleeditmac.h" #include <qcheckbox.h> #include <qframe.h> #include <qlabel.h> #include <qlineedit.h> #include <qpushbutton.h> #include <qlayout.h> #include <qvariant.h> #include <qtooltip.h> #include <qwhatsthis.h> #include <kdebug.h> #include <kmessagebox.h> #include <klocale.h> #include <kapplication.h> // project includes #include "../../core/iptrule.h" #include "../../core/iptchain.h" #include "../../core/iptable.h" #include "../../core/kmfdoc.h" #include "../../core/kmfiptdoc.h" #include "../../core/kmfcheckinput.h" #include "../../core/kmferror.h" #include "../../core/kmferrorhandler.h" /* * Constructs a KMFRuleEditMac which is a child of 'parent', with the * name 'name' and widget flags set to 'f' * * The dialog will by default be modeless, unless you set 'modal' to * TRUE to construct a modal dialog. */ KMFRuleEditMac::KMFRuleEditMac( QWidget* parent, const char* name, WFlags fl ) : KMyFirewallRuleEditorMac( parent, name, fl ) { m_err_handler = new KMFErrorHandler( "KMFRuleEditMac" ); m_check_input = new KMFCheckInput(); m_err = new KMFError(); } /* * Destroys the object and frees any allocated resources */ KMFRuleEditMac::~KMFRuleEditMac() { // no need to delete child widgets, Qt does it all for us } /* * Main event handler. Reimplemented to handle application * font changes */ bool KMFRuleEditMac::event( QEvent* ev ) { bool ret = QWidget::event( ev ); if ( ev->type() == QEvent::ApplicationFontChange ) {} return ret; } void KMFRuleEditMac::loadRule( IPTRule * rule ) { kdDebug() << "void KMFRuleEditMac::loadRule( IPTRule * rule )" << endl, c_src_mac->setChecked( false ); c_inv_src_mac->setChecked( false ); t_src_mac1 ->clear(); t_src_mac2 ->clear(); t_src_mac3 ->clear(); t_src_mac4 ->clear(); t_src_mac5 ->clear(); t_src_mac6 ->clear(); m_rule = rule; QString line = ""; IPTRuleOption* opt = 0; opt = m_rule->getOptionForName("mac_opt"); if ( opt ) { QStringList args = opt->getValues(); QString src, dest; line = *args.at(1); if ( line.isEmpty() || line == "UNDEFINED" ) return; if ( line.startsWith( "! " ) ) { line = line.right( line.length() - 2 ); c_inv_src_mac->setChecked( true ); } int num = 1; QString part = ""; c_src_mac->setChecked( true ); while ( !line.isEmpty() ) { int pos = -1; pos = line.find( ":" ); if ( pos < 0 ) { part = line; line = ""; } else { part = line.left( pos ); line = line.right( line.length() - ( pos + 1 ) ); } switch ( num ) { case 1: t_src_mac1 -> setText( part ); break; case 2: t_src_mac2 -> setText( part ); break; case 3: t_src_mac3 -> setText( part ); break; case 4: t_src_mac4 -> setText( part ); break; case 5: t_src_mac5 -> setText( part ); break; case 6: t_src_mac6 -> setText( part ); break; } num++; } } } void KMFRuleEditMac::accept() { kdDebug() << "KMFRuleEditMac::accept()" << endl; m_rule->chain()->table()->kmfDoc()->startTransaction(); m_rule->saveState(); QString tok1 = t_src_mac1->text().upper(); QString tok2 = t_src_mac2->text().upper(); QString tok3 = t_src_mac3->text().upper(); QString tok4 = t_src_mac4->text().upper(); QString tok5 = t_src_mac5->text().upper(); QString tok6 = t_src_mac6->text().upper(); if ( c_src_mac->isChecked() && ( tok1.isEmpty() || tok2.isEmpty() || tok3.isEmpty() || tok4.isEmpty() || tok5.isEmpty() || tok6.isEmpty() ) ) { const QString & msg = i18n( "One ore more of the fields are empty. Please fill out all fields to define a valid MAC address." ); KMessageBox::error( this, msg ); m_rule->chain()->table()->kmfDoc()->endTransaction(); return ; } QString mac = ""; if ( c_src_mac->isChecked() ) { mac = tok1 + ":" + tok2 + ":" + tok3 + ":" + tok4 + ":" + tok5 + ":" + tok6; m_check_input->checkInput( mac, "MAC", m_err ); if ( ! m_err_handler->showError( m_err ) ) { m_rule->chain()->table()->kmfDoc()->endTransaction(); return ; } } QPtrList<QString>* values = new QPtrList<QString>; QString* op = new QString( "mac_opt" ); if ( c_src_mac->isChecked() && !mac.isEmpty() ) { kdDebug() << "Add new mac option" << endl; QString* src_mac = new QString( mac ); if ( c_inv_src_mac->isChecked() ) { src_mac->prepend( "! " ); } values->append( new QString( "bool:on" ) ); values->append( src_mac ); } emit sigAddRuleOpt( op, values ); m_rule->chain()->table()->kmfDoc()->endTransaction(); emit sigHideMe(); } void KMFRuleEditMac::slotHelp() { kdDebug() << "void KMFRuleEditMac::slotHelp()" << endl; kapp->invokeHelp( "src_mac" ); } void KMFRuleEditMac::reject() { kdDebug() << "void KMFRuleEditMac::reject()" << endl; emit sigHideMe(); } #include "kmfruleeditmac.moc"
Prev | Home | Next |
Developer's Guide to KMyFirewall | Up | Credits and License |