X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=src%2Fipaddressacl.cpp;fp=src%2Fipaddressacl.cpp;h=0516c1d67c422f843786cfea8b5186f0a52a61b3;hb=dec33c63afafabf83c3039e916725cac6faef9b3;hp=0000000000000000000000000000000000000000;hpb=9b22dd53fe62e312c1647310b7ec43aa127090af;p=fms.git diff --git a/src/ipaddressacl.cpp b/src/ipaddressacl.cpp new file mode 100644 index 0000000..0516c1d --- /dev/null +++ b/src/ipaddressacl.cpp @@ -0,0 +1,152 @@ +#include "../include/ipaddressacl.h" +#include "../include/stringfunctions.h" + +#include +#include + +IPAddressACL::IPAddressACL():m_allowbydefault(true) +{ + +} + +const bool IPAddressACL::Add(const std::string &aclentry) +{ + bool allow=m_allowbydefault; + int maskbits=0; + std::string::size_type strpos=std::string::npos; + std::string entrystr=aclentry; + + // look for +/- at beginning of string then strip off + if(entrystr.size()>0) + { + if(entrystr[0]=='-') + { + allow=false; + entrystr.erase(0,1); + } + else if(entrystr[0]=='+') + { + allow=true; + entrystr.erase(0,1); + } + } + + // look for /mask at end of string then strip off and convert to mask + if((strpos=entrystr.find("/"))!=std::string::npos) + { + if(strpos!=entrystr.size()-1) + { + std::string bitmaskstr=entrystr.substr(strpos+1); + entrystr.erase(strpos); + + std::istringstream i(bitmaskstr); + i >> maskbits; + } + else + { + entrystr.erase(strpos); + } + } + + // try to parse address + Poco::Net::IPAddress ip; + if(Poco::Net::IPAddress::tryParse(entrystr,ip)) + { + m_entries.push_back(entry(allow,Poco::Net::IPAddress(CreateMask(maskbits)),ip)); + return true; + } + else + { + return false; + } +} + +const std::string IPAddressACL::CreateMask(const int maskbits) +{ + int bitsleft=maskbits; + int parts[4]={255,255,255,255}; + std::ostringstream ipstr; + + for(int i=3; i>=0; i--) + { + for(int b=0; b<8 && bitsleft>0; b++) + { + parts[i]-=pow((float)2,b); + bitsleft--; + } + } + + ipstr << parts[0] << "." << parts[1] << "." << parts[2] << "." << parts[3]; + + return ipstr.str(); +} + +const bool IPAddressACL::IsAllowed(const Poco::Net::IPAddress &addr) +{ + bool found=false; + bool rval=m_allowbydefault; + + for(std::vector::iterator i=m_entries.begin(); i!=m_entries.end() && found==false; i++) + { + Poco::Net::IPAddress ip1=addr; + Poco::Net::IPAddress ip2=(*i).m_addr; + + //ip1.mask((*i).m_mask); + //ip2.mask((*i).m_mask); + + ip1=MaskAddress(ip1,(*i).m_mask); + ip2=MaskAddress(ip2,(*i).m_mask); + + if(ip1==ip2) + { + found=true; + rval=(*i).m_allow; + } + } + + return rval; +} + +const bool IPAddressACL::IsAllowed(const std::string &addrstr) +{ + Poco::Net::IPAddress ip; + if(Poco::Net::IPAddress::tryParse(addrstr,ip)) + { + return IsAllowed(ip); + } + else + { + return false; + } +} + +Poco::Net::IPAddress IPAddressACL::MaskAddress(const Poco::Net::IPAddress &addr, const Poco::Net::IPAddress &mask) +{ + Poco::Net::IPAddress raddr=addr; + std::vector parts1; + int intparts1[4]={0,0,0,0}; + std::vector parts2; + int intparts2[4]={0,0,0,0}; + int result[4]={0,0,0,0}; + std::ostringstream res; + + StringFunctions::Split(raddr.toString(),".",parts1); + StringFunctions::Split(mask.toString(),".",parts2); + + if(parts1.size()>=4 && parts2.size()>=4) + { + for(int i=0; i<4; i++) + { + StringFunctions::Convert(parts1[i],intparts1[i]); + StringFunctions::Convert(parts2[i],intparts2[i]); + //result[i]=intparts1[i]; + //result[i]|=intparts2[i]&~intparts1[i]; + result[i]=(intparts1[i]&intparts2[i]); + } + res << result[0] << "." << result[1] << "." << result[2] << "." << result[3]; + Poco::Net::IPAddress::tryParse(res.str(),raddr); + } + + return raddr; + +}