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