64ca979081ec090e08a2065d920d175f9fc27078
[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         int parts[4]={0,0,0,0};\r
69         std::ostringstream ipstr;\r
70 \r
71         /*\r
72         for(int i=3; i>=0; i--)\r
73         {\r
74                 for(int b=0; b<8 && bitsleft>0; b++)\r
75                 {\r
76                         parts[i]-=pow((float)2,b);\r
77                         bitsleft--;\r
78                 }\r
79         }\r
80         */\r
81         for(int i=0; i<4; i++)\r
82         {\r
83                 for(int b=7; b>=0 && bitsleft>0; b--)\r
84                 {\r
85                         parts[i]+=pow((float)2,b);\r
86                         bitsleft--;\r
87                 }\r
88         }\r
89 \r
90         ipstr << parts[0] << "." << parts[1] << "." << parts[2] << "." << parts[3];\r
91 \r
92         return ipstr.str();\r
93 }\r
94 \r
95 const bool IPAddressACL::IsAllowed(const Poco::Net::IPAddress &addr)\r
96 {\r
97         bool found=false;\r
98         bool rval=m_allowbydefault;\r
99 \r
100         for(std::vector<entry>::reverse_iterator i=m_entries.rbegin(); i!=m_entries.rend() && found==false; i++)\r
101         {\r
102                 Poco::Net::IPAddress ip1=addr;\r
103                 Poco::Net::IPAddress ip2=(*i).m_addr;\r
104 \r
105                 //ip1.mask((*i).m_mask);\r
106                 //ip2.mask((*i).m_mask);\r
107 \r
108                 ip1=MaskAddress(ip1,(*i).m_mask);\r
109                 ip2=MaskAddress(ip2,(*i).m_mask);\r
110 \r
111                 if(ip1==ip2)\r
112                 {\r
113                         found=true;\r
114                         rval=(*i).m_allow;\r
115                 }\r
116         }\r
117 \r
118         return rval;\r
119 }\r
120 \r
121 const bool IPAddressACL::IsAllowed(const std::string &addrstr)\r
122 {\r
123         Poco::Net::IPAddress ip;\r
124         if(Poco::Net::IPAddress::tryParse(addrstr,ip))\r
125         {\r
126                 return IsAllowed(ip);\r
127         }\r
128         else\r
129         {\r
130                 return false;\r
131         }\r
132 }\r
133 \r
134 Poco::Net::IPAddress IPAddressACL::MaskAddress(const Poco::Net::IPAddress &addr, const Poco::Net::IPAddress &mask)\r
135 {\r
136         Poco::Net::IPAddress raddr=addr;\r
137         std::vector<std::string> parts1;\r
138         int intparts1[4]={0,0,0,0};\r
139         std::vector<std::string> parts2;\r
140         int intparts2[4]={0,0,0,0};\r
141         int result[4]={0,0,0,0};\r
142         std::ostringstream res;\r
143 \r
144         StringFunctions::Split(raddr.toString(),".",parts1);\r
145         StringFunctions::Split(mask.toString(),".",parts2);\r
146 \r
147         if(parts1.size()>=4 && parts2.size()>=4)\r
148         {\r
149                 for(int i=0; i<4; i++)\r
150                 {\r
151                         StringFunctions::Convert(parts1[i],intparts1[i]);\r
152                         StringFunctions::Convert(parts2[i],intparts2[i]);\r
153                         //result[i]=intparts1[i];\r
154                         //result[i]|=intparts2[i]&~intparts1[i];\r
155                         result[i]=(intparts1[i]&intparts2[i]);\r
156                 }\r
157                 res << result[0] << "." << result[1] << "." << result[2] << "." << result[3];\r
158                 Poco::Net::IPAddress::tryParse(res.str(),raddr);\r
159         }\r
160 \r
161         return raddr;\r
162 \r
163 }\r