version 0.3.0
[fms.git] / src / ipaddressacl.cpp
1 #include "../include/ipaddressacl.h"\r
2 #include "../include/stringfunctions.h"\r
3 \r
4 #include <sstream>\r
5 #include <cmath>\r
6 \r
7 IPAddressACL::IPAddressACL():m_allowbydefault(true)\r
8 {\r
9 \r
10 }\r
11 \r
12 const bool IPAddressACL::Add(const std::string &aclentry)\r
13 {\r
14         bool allow=m_allowbydefault;\r
15         int maskbits=0;\r
16         std::string::size_type strpos=std::string::npos;\r
17         std::string entrystr=aclentry;\r
18 \r
19         // look for +/- at beginning of string then strip off\r
20         if(entrystr.size()>0)\r
21         {\r
22                 if(entrystr[0]=='-')\r
23                 {\r
24                         allow=false;\r
25                         entrystr.erase(0,1);\r
26                 }\r
27                 else if(entrystr[0]=='+')\r
28                 {\r
29                         allow=true;\r
30                         entrystr.erase(0,1);\r
31                 }\r
32         }\r
33 \r
34         // look for /mask at end of string then strip off and convert to mask\r
35         if((strpos=entrystr.find("/"))!=std::string::npos)\r
36         {\r
37                 if(strpos!=entrystr.size()-1)\r
38                 {\r
39                         std::string bitmaskstr=entrystr.substr(strpos+1);\r
40                         entrystr.erase(strpos);\r
41 \r
42                         std::istringstream i(bitmaskstr);\r
43                         i >> maskbits;\r
44                 }\r
45                 else\r
46                 {\r
47                         entrystr.erase(strpos);\r
48                 }\r
49         }\r
50 \r
51         // try to parse address\r
52         Poco::Net::IPAddress ip;\r
53         if(Poco::Net::IPAddress::tryParse(entrystr,ip))\r
54         {\r
55                 m_entries.push_back(entry(allow,Poco::Net::IPAddress(CreateMask(maskbits)),ip));\r
56                 return true;\r
57         }\r
58         else\r
59         {\r
60                 return false;\r
61         }\r
62 }\r
63 \r
64 const std::string IPAddressACL::CreateMask(const int maskbits)\r
65 {\r
66         int bitsleft=maskbits;\r
67         int parts[4]={255,255,255,255};\r
68         std::ostringstream ipstr;\r
69 \r
70         for(int i=3; i>=0; i--)\r
71         {\r
72                 for(int b=0; b<8 && bitsleft>0; b++)\r
73                 {\r
74                         parts[i]-=pow((float)2,b);\r
75                         bitsleft--;\r
76                 }\r
77         }\r
78 \r
79         ipstr << parts[0] << "." << parts[1] << "." << parts[2] << "." << parts[3];\r
80 \r
81         return ipstr.str();\r
82 }\r
83 \r
84 const bool IPAddressACL::IsAllowed(const Poco::Net::IPAddress &addr)\r
85 {\r
86         bool found=false;\r
87         bool rval=m_allowbydefault;\r
88 \r
89         for(std::vector<entry>::iterator i=m_entries.begin(); i!=m_entries.end() && found==false; i++)\r
90         {\r
91                 Poco::Net::IPAddress ip1=addr;\r
92                 Poco::Net::IPAddress ip2=(*i).m_addr;\r
93 \r
94                 //ip1.mask((*i).m_mask);\r
95                 //ip2.mask((*i).m_mask);\r
96 \r
97                 ip1=MaskAddress(ip1,(*i).m_mask);\r
98                 ip2=MaskAddress(ip2,(*i).m_mask);\r
99 \r
100                 if(ip1==ip2)\r
101                 {\r
102                         found=true;\r
103                         rval=(*i).m_allow;\r
104                 }\r
105         }\r
106 \r
107         return rval;\r
108 }\r
109 \r
110 const bool IPAddressACL::IsAllowed(const std::string &addrstr)\r
111 {\r
112         Poco::Net::IPAddress ip;\r
113         if(Poco::Net::IPAddress::tryParse(addrstr,ip))\r
114         {\r
115                 return IsAllowed(ip);\r
116         }\r
117         else\r
118         {\r
119                 return false;\r
120         }\r
121 }\r
122 \r
123 Poco::Net::IPAddress IPAddressACL::MaskAddress(const Poco::Net::IPAddress &addr, const Poco::Net::IPAddress &mask)\r
124 {\r
125         Poco::Net::IPAddress raddr=addr;\r
126         std::vector<std::string> parts1;\r
127         int intparts1[4]={0,0,0,0};\r
128         std::vector<std::string> parts2;\r
129         int intparts2[4]={0,0,0,0};\r
130         int result[4]={0,0,0,0};\r
131         std::ostringstream res;\r
132 \r
133         StringFunctions::Split(raddr.toString(),".",parts1);\r
134         StringFunctions::Split(mask.toString(),".",parts2);\r
135 \r
136         if(parts1.size()>=4 && parts2.size()>=4)\r
137         {\r
138                 for(int i=0; i<4; i++)\r
139                 {\r
140                         StringFunctions::Convert(parts1[i],intparts1[i]);\r
141                         StringFunctions::Convert(parts2[i],intparts2[i]);\r
142                         //result[i]=intparts1[i];\r
143                         //result[i]|=intparts2[i]&~intparts1[i];\r
144                         result[i]=(intparts1[i]&intparts2[i]);\r
145                 }\r
146                 res << result[0] << "." << result[1] << "." << result[2] << "." << result[3];\r
147                 Poco::Net::IPAddress::tryParse(res.str(),raddr);\r
148         }\r
149 \r
150         return raddr;\r
151 \r
152 }\r