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

438 lines
14 KiB

/***************************************************************************
begin : Tue Aug 6 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 "kmfcheckinput.h"
// My includes
#include "kmferror.h"
// TQt includes
#include <tqstring.h>
#include <tqregexp.h>
// KDE includes
#include <kdebug.h>
#include <tdelocale.h>
namespace KMF {
KMFCheckInput::KMFCheckInput() {
generateMsgDict();
}
KMFCheckInput::~KMFCheckInput() {}
void KMFCheckInput::checkInput( const TQString& inp, const TQString& inp_type, KMFError* err ) {
// kdDebug() << "KMFCheckInput::checkInput(TQString& inp, const TQString& inp_type)" << endl;
// KMFError *err = new KMFError();
TQString str_input = inp;
if ( str_input.isEmpty() ) {
const TQString msg = "String is Empty.";
err->setErrMsg( msg );
err->setErrType( KMFError::FATAL );
return;
}
if ( inp_type == "IP/NETWORK/FTQHN" ) {
// kdDebug() << "Check for IP/NETWORK/FTQHN" << endl;
bool isIP = checkIP( str_input );
// bool isFTQHN = checkFTQHN( str_input );
bool isNETWORK = checkNetWork( str_input );
if ( !isIP && !isNETWORK ) {
const TQString msg = *m_msg_dict.find( "IP/NETWORK/FTQHN" );
err->setErrMsg( msg );
err->setErrType( KMFError::HINT );
return;
} else {
const TQString msg = "";
err->setErrMsg( msg );
err->setErrType( KMFError::OK );
return;
}
}
if ( inp_type == "PORT" ) {
bool isPORT = checkPORT( str_input );
if ( !isPORT ) {
const TQString msg = *m_msg_dict.find( "PORT" );
err->setErrMsg( msg );
err->setErrType( KMFError::NORMAL );
return;
} else {
const TQString msg = "";
err->setErrMsg( msg );
err->setErrType( KMFError::OK );
return;
}
}
if ( inp_type == "MULTIPORT" ) {
bool isMULTIPORT = checkMULTIPORT( str_input );
if ( !isMULTIPORT ) {
const TQString msg = *m_msg_dict.find( "MULTIPORT" );
err->setErrMsg( msg );
err->setErrType( KMFError::NORMAL );
return;
} else {
const TQString msg = "";
err->setErrMsg( msg );
err->setErrType( KMFError::OK );
return;
}
}
if ( inp_type == "PORT/PORTRANGE" ) {
bool isPORT = checkPORT( str_input );
bool isPORTRANGE = checkPORTRANGE( str_input );
if ( !isPORT && !isPORTRANGE ) {
const TQString msg = *m_msg_dict.find( "PORT" );
err->setErrMsg( msg );
err->setErrType( KMFError::NORMAL );
return;
} else {
const TQString msg = "";
err->setErrMsg( msg );
err->setErrType( KMFError::OK );
return;
}
}
if ( inp_type == "FTQHN" ) {
bool isFTQHN = checkFTQHN( str_input );
if ( !isFTQHN ) {
const TQString msg = *m_msg_dict.find( "FTQHN" );
err->setErrMsg( msg );
err->setErrType( KMFError::NORMAL );
return;
} else {
const TQString msg = "";
err->setErrMsg( msg );
err->setErrType(KMFError::OK );
return;
}
}
if ( inp_type == "IP" ) {
bool isIP = checkIP( str_input );
if ( !isIP ) {
const TQString msg = *m_msg_dict.find( "IP" );
err->setErrMsg( msg );
err->setErrType( KMFError::NORMAL );
return;
} else {
const TQString msg = "";
err->setErrMsg( msg );
err->setErrType( KMFError::OK );
return;
}
}
if ( inp_type == "CHAINNAME" ) {
bool isValid = checkChainName( str_input );
if ( !isValid ) {
const TQString msg = *m_msg_dict.find( "CHAINNAME" );
err->setErrMsg( msg );
err->setErrType( KMFError::NORMAL );
return;
} else {
const TQString msg = "";
err->setErrMsg( msg );
err->setErrType( KMFError::OK );
return;
}
}
if ( inp_type == "RULENAME" ) {
bool isValid = checkRuleName( str_input );
if ( !isValid ) {
const TQString msg = *m_msg_dict.find( "RULENAME" );
err->setErrMsg( msg );
err->setErrType( KMFError::NORMAL );
return;
} else {
const TQString msg = "";
err->setErrMsg( msg );
err->setErrType( KMFError::OK );
return;
}
}
if ( inp_type == "MAC" ) {
bool isValid = checkMAC( str_input );
if ( !isValid ) {
const TQString msg = *m_msg_dict.find( "MAC" );
err->setErrMsg( msg );
err->setErrType( KMFError::NORMAL );
return;
} else {
const TQString msg = "";
err->setErrMsg( msg );
err->setErrType( KMFError::OK );
return;
}
}
const TQString msg = "Misuse of this function.";
err->setErrMsg( msg );
err->setErrType( KMFError::FATAL );
return;
}
bool KMFCheckInput::checkIP( TQString inp ) {
TQRegExp exp( "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$" );
// kdDebug() << "RegEx isValid: " << exp.isValid() << endl;
if ( inp.contains( exp ) ) {
int pos;
TQString str_num;
bool valid = true;
while ( !inp.isEmpty() ) {
pos = inp.find( "." );
if ( pos > -1 ) {
str_num = inp.left( pos );
// kdDebug() << "IP Num Part: " << str_num << endl;
inp = inp.right( inp.length() - ( pos + 1 ) );
// kdDebug() << "Rest: " << inp << endl;
int val = str_num.toInt();
// kdDebug() << "Val: " << val << endl;
if ( val < 0 || val > 255 ) {
valid = false;
}
} else {
str_num = inp;
// kdDebug() << "IP Num Part: " << str_num << endl;
inp = "";
// kdDebug() << "Rest: " << inp << endl;
int val = str_num.toInt();
// kdDebug() << "Val: " << val << endl;
if ( val < 0 || val > 255 ) {
valid = false;
}
}
}
return valid;
} else
return false;
}
bool KMFCheckInput::checkNetMask ( TQString inp ) {
TQRegExp exp( "^[0-9]{1,2}$" );
// kdDebug() << "RegEx isValid: " << exp.isValid() << endl;
if ( inp.contains( exp ) ) {
int val = inp.toInt();
if ( val < 0 || val > 24 ) {
kdDebug() << "Mask must not be > 24" << endl;
return false;
} else {
return true;
}
} else {
return false;
}
}
bool KMFCheckInput::checkPORT ( TQString inp ) {
TQRegExp exp( "^[0-9]{1,5}$" );
// kdDebug() << "RegEx isValid: " << exp.isValid() << endl;
if ( inp.contains( exp ) ) {
int val = inp.toInt();
if ( val < 0 || val > 65535 ) {
kdDebug() << "Port must not be > 65535" << endl;
return false;
} else {
return true;
}
} else {
return false;
}
}
bool KMFCheckInput::checkMULTIPORT ( TQString inp ) {
TQString tmp = inp;
while ( !tmp.isEmpty() ) {
TQString port = "";
int pos = tmp.find( "," );
if ( pos == -1 ) {
port = tmp;
port = port.stripWhiteSpace();
tmp = "";
if ( !checkPORT( port ) ) {
return false;
}
} else {
port = tmp.left( pos );
port = port.stripWhiteSpace();
kdDebug() << "Found for port: " << port << endl;
tmp = tmp.right( tmp.length() - ( pos + 1 ) );
kdDebug() << "Rest: " << tmp << endl;
if ( !checkPORT( port ) ) {
return false;
}
}
}
return true;
}
bool KMFCheckInput::checkPORTRANGE ( TQString inp ) {
bool valid_1 = false;
bool valid_2 = false;
kdDebug() << "Checking for PORTRANGE: " << endl;
int delimiter = inp.find( ":" );
if ( delimiter == -1 ) {
kdDebug() << "This is no port range" << endl;
return false;
} else {
TQString port1 = inp.left( delimiter );
TQString port2 = inp.right( inp.length() - ( delimiter + 1 ) );
valid_1 = checkPORT ( port1 );
valid_2 = checkPORT ( port2 );
if ( valid_1 && valid_2 ) {
return true;
} else {
return false;
}
}
return false;
}
bool KMFCheckInput::checkNetWork ( TQString inp ) {
bool valid_address = false;
bool valid_mask = false;
kdDebug() << "Checking for NETWORK: " << endl;
int delimiter = inp.find( "/" );
if ( delimiter == -1 ) {
kdDebug() << "This is no network" << endl;
return false;
} else {
TQString addr = inp.left( delimiter );
TQString mask = inp.right( inp.length() - ( delimiter + 1 ) );
kdDebug() << "Found address: " << addr << endl;
kdDebug() << "Found mask: " << mask << endl;
if ( mask.isEmpty() ) {
// kdDebug() << "Mask is Empty\n" << endl;
return false;
} else {
valid_address = checkIP( addr );
valid_mask = checkIP( mask );
// kdDebug() << "Mask address valid: " << valid_mask << endl;
if ( !valid_mask ) {
valid_mask = checkNetMask ( mask );
// kdDebug() << "Mask number valid: " << valid_mask << endl;
}
if ( !valid_address || !valid_mask ) {
// kdDebug() << "This is no valid Network" << endl;
return false;
} else {
// kdDebug() << "This is a valid Network" << endl;
return true;
}
}
}
}
bool KMFCheckInput::checkFTQHN( TQString inp ) {
bool valid = TRUE;
// TQRegExp exp( "^(\\w{1,256})\\.([a-z]{2,6})$", false );
TQRegExp exp( "^[0-9a-zA-Z_-\\.]{3,256}$", false );
if ( !inp.contains( exp ) )
valid = false;
return valid;
}
bool KMFCheckInput::checkMAC( TQString inp ) {
bool valid = TRUE;
TQRegExp exp( "^[0-9a-fA-F]{2,2}\\:[0-9a-fA-F]{2,2}\\:[0-9a-fA-F]{2,2}\\:[0-9a-fA-F]{2,2}\\:[0-9a-fA-F]{2,2}\\:[0-9a-fA-F]{2,2}$", false );
if ( !inp.contains( exp ) )
valid = false;
return valid;
}
bool KMFCheckInput::checkChainName( TQString inp ) {
bool valid = TRUE;
TQRegExp exp( "^[a-zA-Z0-9_]{1,29}$", false );
if ( !inp.contains( exp ) )
valid = false;
return valid;
}
bool KMFCheckInput::checkRuleName( TQString inp ) {
bool valid = TRUE;
TQRegExp exp( "^[a-zA-Z0-9_-]{1,20}$", false );
if ( !inp.contains( exp ) )
valid = false;
return valid;
}
void KMFCheckInput::generateMsgDict() {
TQString key = "IP/NETWORK/FTQHN";
const TQString *msg = new TQString( i18n( "<p><b>This is not a numerical IP or NETWORK therefore this can only be a HOSTNAME;</b><br>"
"there is nothing wrong with that except that you will need to "
"have a working name resolution (e.g. DNS) at firewall startup<br>"
"and hence the network needs to be up before the firewall can be started. "
"Therefore, it is highly recommended that you only use numerical IP/NETWORK addresses, "
"but it will also work that way.<br>"
"<b>Please note that it is not possible to guarantee that the hostname is valid - it is "
"your job to make sure that the hostname is right.</b>"
"<p><ul><li>An IP address has the format: [0-255].[0-255].[0-255].[0-255]</li>"
"<li>A network may look like 123.123.123.0/255.255.255.0 or 123.123.123.0/24 (these two are identical.)</li>"
"<li>A hostname looks like www.debian.org or my-host.the-net.org</li></ul>" ) );
m_msg_dict.insert( key, msg );
key = "IP";
const TQString *msg2 = new TQString( i18n( "<p>This is not a valid IP address or hostname."
"<p>An IP address has the format: [0-255].[0-255].[0-255].[0-255]" ) );
m_msg_dict.insert( key, msg2 );
key = "FTQHN";
const TQString *msg3 = new TQString( i18n( "<p>This is not a valid IP address or hostname."
"<p>A hostname looks like www.suse.com" ) );
m_msg_dict.insert( key, msg3 );
key = "CHAINNAME";
const TQString *msg4 = new TQString( i18n( "<p>This is not a valid chain name."
"<p>Chain names <b>must not</b> contain special characters (like whitespace, ?, &, %, etc.) "
"and <b>must not</b> be longer then 29 characters" ) );
m_msg_dict.insert( key, msg4 );
key = "MAC";
const TQString *msg5 = new TQString( i18n( "<p>This is not a valid MAC address."
"<p>A MAC address has six hex digits from 00-FF<br>A valid address could be: <b>02:E4:5A:90:1B:3C</b>" ) );
m_msg_dict.insert( key, msg5 );
key = "PORT";
const TQString *msg6 = new TQString( i18n( "<p><b>This is not a valid numeric PORT number.</b><br>"
"Port numbers are all numbers from 1 to 65535.<br> "
"If you specified a service name (e.g. ssh or www) like they are listed "
"in <i>/etc/services</i> the rule will work, but it is highly recommended "
"that you only use numerical port numbers to avoid problems when having a broken (faked) "
"/etc/services file.<br>"
"<b>Please think twice about before you use service names, port numbers are much safer.</b>" ) );
m_msg_dict.insert( key, msg6 );
key = "MULTIPORT";
const TQString *msg7 = new TQString( i18n( "<p>This is not a valid MULTIPORT string.<br>"
"A MULTIPORT strings is a comma separated list of PORT numbers.<br>"
"Please not that service names are not supported within MULTIPORT strings." ) );
m_msg_dict.insert( key, msg7 );
key = "RULENAME";
const TQString *msg8 = new TQString( i18n( "<p>This is not a valid rule name."
"<p>Rule names <b>must not</b> contain special characters (like whitespace, ?, &, %, etc.) "
"and <b>must not</b> be longer then 20 characters" ) );
m_msg_dict.insert( key, msg8 );
}
}