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