Revision e8c2c6f2
Added by Viktor Gurov almost 5 years ago
src/etc/inc/openvpn.attributes.php | ||
---|---|---|
51 | 51 |
return -1;; |
52 | 52 |
} |
53 | 53 |
|
54 |
function parse_cisco_acl_rule($rule, $devname, $dir) { |
|
54 |
function parse_cisco_acl_rule($rule, $devname, $dir, $proto) {
|
|
55 | 55 |
$rule_orig = $rule; |
56 | 56 |
$rule = explode(" ", $rule); |
57 | 57 |
$tmprule = ""; |
58 | 58 |
$index = 0; |
59 | 59 |
|
60 | 60 |
if ($rule[$index] == "permit") { |
61 |
$tmprule = "pass {$dir} quick on {$devname} ";
|
|
61 |
$startrule = "pass {$dir} quick on {$devname} ";
|
|
62 | 62 |
} else if ($rule[$index] == "deny") { |
63 |
$tmprule = "block {$dir} quick on {$devname} ";
|
|
63 |
$startrule = "block {$dir} quick on {$devname} ";
|
|
64 | 64 |
} else { |
65 | 65 |
return; |
66 | 66 |
} |
... | ... | |
69 | 69 |
|
70 | 70 |
switch ($rule[$index]) { |
71 | 71 |
case "ip": |
72 |
$tmprule .= "inet "; |
|
73 | 72 |
break; |
74 | 73 |
case "icmp": |
74 |
$icmp = ($proto == "inet") ? "icmp" : "ipv6-icmp"; |
|
75 |
$tmprule .= "proto {$icmp} "; |
|
76 |
break; |
|
75 | 77 |
case "tcp": |
76 | 78 |
case "udp": |
77 | 79 |
$tmprule .= "proto {$rule[$index]} "; |
... | ... | |
85 | 87 |
/* Source */ |
86 | 88 |
if (trim($rule[$index]) == "host") { |
87 | 89 |
$index++; |
90 |
if ((is_ipaddrv4(trim($rule[$index])) && ($proto == "inet")) || |
|
91 |
(is_ipaddrv6(trim($rule[$index])) && ($proto == "inet6"))) { |
|
92 |
$tmprule .= "from {$rule[$index]} "; |
|
93 |
$index++; |
|
94 |
} else { |
|
95 |
syslog(LOG_WARNING, "Error parsing rule {$rule_orig}: Invalid source host '{$rule[$index]}'."); |
|
96 |
return; |
|
97 |
} |
|
98 |
} elseif (is_subnetv6(trim($rule[$index])) && ($proto == "inet6")) { |
|
88 | 99 |
$tmprule .= "from {$rule[$index]} "; |
89 | 100 |
$index++; |
90 |
} else if (trim($rule[$index]) == "any") {
|
|
101 |
} elseif (trim($rule[$index]) == "any") { |
|
91 | 102 |
$tmprule .= "from any "; |
92 | 103 |
$index++; |
93 | 104 |
} else { |
94 | 105 |
$network = $rule[$index]; |
95 | 106 |
$netmask = $rule[++$index]; |
96 | 107 |
|
97 |
|
|
98 |
if(!is_ipaddr($network)) { |
|
108 |
if (is_ipaddrv4($network) && ($proto == "inet")) { |
|
109 |
try { |
|
110 |
$netmask = cisco_to_cidr($netmask); |
|
111 |
} catch(Exception $e) { |
|
112 |
syslog(LOG_WARNING, "Error parsing rule {$rule_orig}: Invalid source netmask '$netmask'."); |
|
113 |
return; |
|
114 |
} |
|
115 |
$tmprule .= "from {$network}/{$netmask}"; |
|
116 |
} else { |
|
99 | 117 |
syslog(LOG_WARNING, "Error parsing rule {$rule_orig}: Invalid source network '$network'."); |
100 | 118 |
return; |
101 | 119 |
} |
102 | 120 |
|
103 |
try { |
|
104 |
$netmask = cisco_to_cidr($netmask); |
|
105 |
} catch(Exception $e) { |
|
106 |
syslog(LOG_WARNING, "Error parsing rule {$rule_orig}: Invalid source netmask '$netmask'."); |
|
107 |
return; |
|
108 |
} |
|
109 |
$tmprule .= "from {$network}/{$netmask} "; |
|
110 |
|
|
111 | 121 |
$index++; |
112 | 122 |
} |
113 | 123 |
|
... | ... | |
152 | 162 |
/* Destination */ |
153 | 163 |
if (trim($rule[$index]) == "host") { |
154 | 164 |
$index++; |
165 |
if ((is_ipaddrv4(trim($rule[$index])) && ($proto == "inet")) || |
|
166 |
(is_ipaddrv6(trim($rule[$index])) && ($proto == "inet6"))) { |
|
167 |
$tmprule .= "to {$rule[$index]} "; |
|
168 |
$index++; |
|
169 |
} else { |
|
170 |
syslog(LOG_WARNING, "Error parsing rule {$rule_orig}: Invalid destination host '{$rule[$index]}'."); |
|
171 |
return; |
|
172 |
} |
|
173 |
} elseif (is_subnetv6(trim($rule[$index])) && ($proto == "inet6")) { |
|
155 | 174 |
$tmprule .= "to {$rule[$index]} "; |
156 | 175 |
$index++; |
157 |
} else if (trim($rule[$index]) == "any") {
|
|
176 |
} elseif (trim($rule[$index]) == "any") { |
|
158 | 177 |
$tmprule .= "to any "; |
159 | 178 |
$index++; |
160 | 179 |
} else { |
161 | 180 |
$network = $rule[$index]; |
162 | 181 |
$netmask = $rule[++$index]; |
163 | 182 |
|
164 |
|
|
165 |
if(!is_ipaddr($network)) { |
|
183 |
if (is_ipaddrv4($network) && ($proto == "inet")) { |
|
184 |
try { |
|
185 |
$netmask = cisco_to_cidr($netmask); |
|
186 |
} catch(Exception $e) { |
|
187 |
syslog(LOG_WARNING, "Error parsing rule {$rule_orig}: Invalid destination network '$network'."); |
|
188 |
return; |
|
189 |
} |
|
190 |
$tmprule .= "to {$network}/{$netmask}"; |
|
191 |
} else { |
|
166 | 192 |
syslog(LOG_WARNING, "Error parsing rule {$rule_orig}: Invalid destination network '$network'."); |
167 | 193 |
return; |
168 | 194 |
} |
169 | 195 |
|
170 |
try { |
|
171 |
$netmask = cisco_to_cidr($netmask); |
|
172 |
} catch(Exception $e) { |
|
173 |
syslog(LOG_WARNING, "Error parsing rule {$rule_orig}: Invalid destination netmask '$netmask'."); |
|
174 |
return; |
|
175 |
} |
|
176 |
$tmprule .= "to {$network}/{$netmask} "; |
|
177 |
|
|
178 | 196 |
$index++; |
179 | 197 |
} |
180 | 198 |
|
... | ... | |
216 | 234 |
$index++; |
217 | 235 |
} |
218 | 236 |
|
237 |
$tmprule = $startrule . $proto . " " . $tmprule; |
|
219 | 238 |
return $tmprule; |
220 | 239 |
} |
221 | 240 |
|
... | ... | |
226 | 245 |
} |
227 | 246 |
$finalrules = ""; |
228 | 247 |
if (is_array($attribs['ciscoavpair'])) { |
229 |
$inrules = array(); |
|
230 |
$outrules = array(); |
|
248 |
$inrules = array('inet' => array(), 'inet6' => array());
|
|
249 |
$outrules = array('inet' => array(), 'inet6' => array());
|
|
231 | 250 |
foreach ($attribs['ciscoavpair'] as $avrules) { |
232 | 251 |
$rule = explode("=", $avrules); |
233 | 252 |
$dir = ""; |
... | ... | |
250 | 269 |
continue; |
251 | 270 |
} |
252 | 271 |
|
253 |
$tmprule = parse_cisco_acl_rule($rule[1], $dev, $dir); |
|
272 |
if (strstr($rule[0], "ipv6")) { |
|
273 |
$proto = "inet6"; |
|
274 |
} else { |
|
275 |
$proto = "inet"; |
|
276 |
} |
|
277 |
|
|
278 |
$tmprule = parse_cisco_acl_rule($rule[1], $dev, $dir, $proto); |
|
254 | 279 |
|
255 | 280 |
if ($dir == "in") { |
256 |
$inrules[$rindex] = $tmprule; |
|
281 |
$inrules[$proto][$rindex] = $tmprule;
|
|
257 | 282 |
} else if ($dir == "out") { |
258 |
$outrules[$rindex] = $tmprule; |
|
283 |
$outrules[$proto][$rindex] = $tmprule;
|
|
259 | 284 |
} |
260 | 285 |
} |
261 | 286 |
|
262 | 287 |
|
263 | 288 |
$state = ""; |
264 |
if (!empty($outrules)) { |
|
265 |
$state = "no state"; |
|
266 |
} |
|
267 |
ksort($inrules, SORT_NUMERIC); |
|
268 |
foreach ($inrules as $inrule) { |
|
269 |
$finalrules .= "{$inrule} {$state}\n"; |
|
270 |
} |
|
271 |
if (!empty($outrules)) { |
|
272 |
ksort($outrules, SORT_NUMERIC); |
|
273 |
foreach ($outrules as $outrule) { |
|
274 |
$finalrules .= "{$outrule} {$state}\n"; |
|
289 |
foreach (array('inet', 'inet6') as $ip) { |
|
290 |
if (!empty($outrules[$ip])) { |
|
291 |
$state = "no state"; |
|
292 |
} |
|
293 |
ksort($inrules[$ip], SORT_NUMERIC); |
|
294 |
foreach ($inrules[$ip] as $inrule) { |
|
295 |
$finalrules .= "{$inrule} {$state}\n"; |
|
296 |
} |
|
297 |
if (!empty($outrules[$ip])) { |
|
298 |
ksort($outrules[$ip], SORT_NUMERIC); |
|
299 |
foreach ($outrules[$ip] as $outrule) { |
|
300 |
$finalrules .= "{$outrule} {$state}\n"; |
|
301 |
} |
|
275 | 302 |
} |
276 | 303 |
} |
277 | 304 |
} |
Also available in: Unified diff
OpenVPN+RADIUS+Cisco-AVPair IPv6 ACL. Issue #10454