Project

General

Profile

« Previous | Next » 

Revision e8c2c6f2

Added by Viktor Gurov almost 5 years ago

OpenVPN+RADIUS+Cisco-AVPair IPv6 ACL. Issue #10454

View differences:

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