diff options
Diffstat (limited to 'lanbrowsing/lisa/addressvalidator.cpp')
-rw-r--r-- | lanbrowsing/lisa/addressvalidator.cpp | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/lanbrowsing/lisa/addressvalidator.cpp b/lanbrowsing/lisa/addressvalidator.cpp new file mode 100644 index 00000000..aa292806 --- /dev/null +++ b/lanbrowsing/lisa/addressvalidator.cpp @@ -0,0 +1,228 @@ +/* addressvalidator.cpp + * + * Copyright (c) 2000, Alexander Neundorf + * neundorf@kde.org + * + * You may distribute under the terms of the GNU General Public + * License as specified in the COPYING file. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include "addressvalidator.h" +#include "mystring.h" + +#include <stdlib.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <sys/socket.h> +#include <iostream> +using namespace std; + +#ifdef LISA_DEBUG +#undef LISA_DEBUG +#endif +#define LISA_DEBUG 0 +#define dcerr if (LISA_DEBUG==1) std::cerr<<"AddressValidator::" + +AddressValidator::AddressValidator(const MyString& addressSpecs) +//this is 127.0.0.0 +:localhostNet(htonl(0x7f000000)) +//with mask 255.255.255.0 +,localhostMask(htonl(0xffffff00)) +{ + clearSpecs(); + MyString tmp=addressSpecs; + setValidAddresses(tmp); +} + +AddressValidator::AddressValidator() + //this is 127.0.0.0 + :localhostNet(htonl(0x7f000000)) + //with mask 255.255.255.0 + ,localhostMask(htonl(0xffffff00)) +{ + clearSpecs(); +} + +AddressValidator::~AddressValidator() +{} + +void AddressValidator::configure(Config& config) +{ + MyString tmp=stripWhiteSpace(config.getEntry("AllowedAddresses","")); + tmp=tmp+";"; + setValidAddresses(tmp); + dcerr<<"configure(): "<<tmp<<std::endl; +} + + +void AddressValidator::setValidAddresses(MyString addressSpecs) +{ + dcerr<<"setValidAddresses"<<std::endl; + allowedHosts=addressSpecs; + MyString nextPart; + while (!addressSpecs.isEmpty()) + { + dcerr<<"setValidAddresses: "<<addressSpecs<<std::endl; + int pos=addressSpecs.find(";"); + nextPart=addressSpecs.left(pos); + addressSpecs=addressSpecs.mid(pos+1); + dcerr<<"setValidAddresses: nextPart: "<<nextPart<<std::endl; + if ((nextPart.contains('.')==3) && (nextPart.contains('-')==0)) + { + addSpec(EXACTADDR_SPEC,inet_addr(nextPart.data())); + dcerr<<"setValidAddresses: exact addr: " + <<std::ios::hex<<inet_addr(nextPart.data())<<std::ios::dec<<std::endl; + } + else if ((nextPart.contains('-')==1) && (nextPart.contains('.')==6)) + { + int p2=nextPart.find("-"); + MyString from=nextPart.left(p2); + MyString to=nextPart.mid(p2+1); + addSpec(RANGE_SPEC,ntohl(inet_addr(from.data())),ntohl(inet_addr(to.data()))); + } + else if ((nextPart.contains('-')==4) && (nextPart.contains('.')==3)) + { + unsigned int i1=0; + unsigned int i2=0; + int p2=0; + MyString rest=nextPart+'.'; + MyString digit; + + for (int i=0; i<4; i++) + { + p2=rest.find("-"); + digit=rest.left(p2); + i1=i1<<8; + i1+=atoi(digit.data()); + rest=rest.mid(p2+1); + p2=rest.find("."); + digit=rest.left(p2); + i2=i2<<8; + i2+=atoi(digit.data()); + rest=rest.mid(p2+1); + }; + addSpec(MULTIRANGE_SPEC,i1,i2); + } + else + { + pos=nextPart.find('/'); + MyString netStr=nextPart.left(pos); + MyString maskStr=nextPart.mid(pos+1); + int mask=inet_addr(maskStr.data()); + int net= (inet_addr(netStr.data()) & mask); + dcerr<<"setValidAddresses: net/mask: " + <<std::ios::hex<<net<<"/"<<mask<<std::ios::dec<<std::endl; + addSpec(NETMASK_SPEC,net,mask); + } + } +} + +void AddressValidator::clearSpecs() +{ + allowedHosts=""; + for (int i=0; i<MAX_SPECS; i++) + { + specs[i].address=0; + specs[i].mask=0; + specs[i].typeOfSpec=NO_SPEC; + } +} + +void AddressValidator::addSpec(int type, int address, int mask) +{ + for (int i=0; i<MAX_SPECS; i++) + { + if (specs[i].typeOfSpec==NO_SPEC) + { + specs[i].address=address; + specs[i].mask=mask; + specs[i].typeOfSpec=type; + return; + } + } +} + +int AddressValidator::isValid(int addressNBO) +{ + dcerr<<"isValid: " + <<std::ios::hex<<addressNBO<<std::ios::dec<<std::endl; + //localhost is always allowed + dcerr<<"isValid() local net: "<< + std::ios::hex<<localhostNet<<" mask: "<<localhostMask<<" AND: "<<(addressNBO & + localhostMask)<<std::ios::dec<<std::endl; + if ((addressNBO & localhostMask) == localhostNet) + return 1; + + for (int i=0; i<MAX_SPECS; i++) + { + if (specs[i].typeOfSpec==NO_SPEC) + { + //since the specifications are always entered from the beginning + //of the array, we already passed the last one if we get here + //so we can return now "it is invalid !" ;-) + return 0; + //continue; + } + else if (specs[i].typeOfSpec==EXACTADDR_SPEC) + { + dcerr<<"isValid: comparing " + <<std::ios::hex<<specs[i].address<<std::ios::dec<<std::endl; + if (addressNBO==specs[i].address) + { + dcerr<<"isValid: exact address"<<std::endl; + return 1; // this one is allowed to :-) + } + } + else if (specs[i].typeOfSpec==NETMASK_SPEC) + { + dcerr<<"isValid: ANDing "<< + std::ios::hex<<(addressNBO & specs[i].mask)<<" "<< + specs[i].address<<std::ios::dec<<std::endl; + if ((addressNBO & specs[i].mask) == specs[i].address) + { + dcerr<<"isValid: net/mask"<<std::endl; + return 1; + } + } + else if (specs[i].typeOfSpec==RANGE_SPEC) + { + if ((ntohl(addressNBO)>=specs[i].address) && (ntohl(addressNBO)<=specs[i].mask)) + { + dcerr<<"isValid: range"<<std::endl; + return 1; + } + } + else if (specs[i].typeOfSpec==MULTIRANGE_SPEC) + { + unsigned int addr=ntohl(addressNBO); + dcerr<<"isValid ntohl="<<hex<<addr<<" addr: "<<specs[i].address<<" ma: "<<specs[i].mask<<dec<<std::endl; + unsigned int mask=0x000000ff; + int failure=0; + for (int j=0; j<4; j++) + { + dcerr<<"isValid "<<hex<<"mask="<<mask<<" addr="<<(addr&mask)<<" addr="<<(specs[i].address & mask)<<" ma="<<(specs[i].mask&mask)<<std::endl; + if (((addr & mask) < (specs[i].address & mask)) + || ((addr & mask) > (specs[i].mask & mask))) + { + failure=1; + break; + } + mask=mask<<8; + } + dcerr<<"isValid: multirange"<<std::endl; + if (!failure) + return 1; + } + } + //if ((addressNBO==htonl(0x0a040801)) || (addressNBO==htonl(0xc0a80001))) return 0; + dcerr<<"isValid: invalid address"<<std::endl; + return 0; +} + |