Project

General

Profile

Download (5.12 KB) Statistics
| Branch: | Tag: | Revision:
1 5b4ee05e Ermal
<?php
2
/*
3 ce77a9c4 Phil Davis
	openvpn.attributes.php
4 b37a2e8c Phil Davis
	Copyright (C) 2011-2012 Ermal Luçi
5 ce77a9c4 Phil Davis
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
6
	All rights reserved.
7
8
	Redistribution and use in source and binary forms, with or without
9
	modification, are permitted provided that the following conditions are met:
10
11
	1. Redistributions of source code must retain the above copyright notice,
12
	   this list of conditions and the following disclaimer.
13
14
	2. Redistributions in binary form must reproduce the above copyright
15
	   notice, this list of conditions and the following disclaimer in the
16
	   documentation and/or other materials provided with the distribution.
17
18
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
22
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
	POSSIBILITY OF SUCH DAMAGE.
28 5b4ee05e Ermal
*/
29
30
if (empty($common_name)) {
31
	$common_name = getenv("common_name");
32 b37a2e8c Phil Davis
	if (empty($common_name)) {
33 5b4ee05e Ermal
		$common_name = getenv("username");
34 b37a2e8c Phil Davis
	}
35 5b4ee05e Ermal
}
36
37
$devname = getenv("dev");
38 b37a2e8c Phil Davis
if (empty($devname)) {
39 5b4ee05e Ermal
	$devname = "openvpn";
40 b37a2e8c Phil Davis
}
41 5b4ee05e Ermal
42
function cisco_to_cidr($addr) {
43 b37a2e8c Phil Davis
	if (!is_ipaddr($addr)) {
44 5b4ee05e Ermal
		return 0;
45 b37a2e8c Phil Davis
	}
46 5b4ee05e Ermal
	$mask = decbin(~ip2long($addr));
47
	$mask = substr($mask, -32);
48
	$k = 0;
49
	for ($i = 0; $i <= 32; $i++) {
50
		$k += intval($mask[$i]);
51
	}
52
	return $k;
53
}
54
55
function cisco_extract_index($prule) {
56 b37a2e8c Phil Davis
57 5b4ee05e Ermal
	$index = explode("#", $prule);
58 b37a2e8c Phil Davis
	if (is_numeric($index[1])) {
59 5b4ee05e Ermal
		return intval($index[1]);
60 b37a2e8c Phil Davis
	} else {
61 5b4ee05e Ermal
		syslog(LOG_WARNING, "Error parsing rule {$prule}: Could not extract index");
62 b37a2e8c Phil Davis
	}
63 5b4ee05e Ermal
	return -1;;
64
}
65
66
function parse_cisco_acl($attribs) {
67
	global $devname, $attributes;
68 b37a2e8c Phil Davis
	if (!is_array($attribs)) {
69 5b4ee05e Ermal
		return "";
70 b37a2e8c Phil Davis
	}
71 5b4ee05e Ermal
	$finalrules = "";
72
	if (is_array($attribs['ciscoavpair'])) {
73
		$inrules = array();
74
		$outrules = array();
75
		foreach ($attribs['ciscoavpair'] as $avrules) {
76
			$rule = explode("=", $avrules);
77
			$dir = "";
78
			if (strstr($rule[0], "inacl")) {
79
				$dir = "in";
80 b37a2e8c Phil Davis
			} else if (strstr($rule[0], "outacl")) {
81 5b4ee05e Ermal
				$dir = "out";
82 b37a2e8c Phil Davis
			} else if (strstr($rule[0], "dns-servers")) {
83 5b4ee05e Ermal
				$attributes['dns-servers'] = explode(" ", $rule[1]);
84
				continue;
85
			} else if (strstr($rule[0], "route")) {
86 b37a2e8c Phil Davis
				if (!is_array($attributes['routes'])) {
87 5b4ee05e Ermal
					$attributes['routes'] = array();
88 b37a2e8c Phil Davis
				}
89 9f293b1c jim-p
				$attributes['routes'][] = $rule[1];
90 5b4ee05e Ermal
				continue;
91 b37a2e8c Phil Davis
			}
92 5b4ee05e Ermal
			$rindex = cisco_extract_index($rule[0]);
93 b37a2e8c Phil Davis
			if ($rindex < 0) {
94 5b4ee05e Ermal
				continue;
95 b37a2e8c Phil Davis
			}
96 5b4ee05e Ermal
97
			$rule = $rule[1];
98
			$rule = explode(" ", $rule);
99
			$tmprule = "";
100
			$index = 0;
101
			$isblock = false;
102 b37a2e8c Phil Davis
			if ($rule[$index] == "permit") {
103 5b4ee05e Ermal
				$tmprule = "pass {$dir} quick on {$devname} ";
104 b37a2e8c Phil Davis
			} else if ($rule[$index] == "deny") {
105 5b4ee05e Ermal
				//continue;
106
				$isblock = true;
107
				$tmprule = "block {$dir} quick on {$devname} ";
108
			} else {
109
				continue;
110
			}
111
112
			$index++;
113
114
			switch ($rule[$index]) {
115 b37a2e8c Phil Davis
				case "tcp":
116
				case "udp":
117
					$tmprule .= "proto {$rule[$index]} ";
118
					break;
119 5b4ee05e Ermal
			}
120
121
			$index++;
122
			/* Source */
123
			if (trim($rule[$index]) == "host") {
124
				$index++;
125
				$tmprule .= "from {$rule[$index]} ";
126
				$index++;
127 b37a2e8c Phil Davis
				if ($isblock == true) {
128 5b4ee05e Ermal
					$isblock = false;
129 b37a2e8c Phil Davis
				}
130 5b4ee05e Ermal
			} else if (trim($rule[$index]) == "any") {
131 b0ccc67b Phil Davis
				$tmprule .= "from any ";
132 5b4ee05e Ermal
				$index++;
133
			} else {
134 8340d956 Renato Botelho
				$tmprule .= "from {$rule[$index]}";
135 5b4ee05e Ermal
				$index++;
136
				$netmask = cisco_to_cidr($rule[$index]);
137
				$tmprule .= "/{$netmask} ";
138
				$index++;
139 b37a2e8c Phil Davis
				if ($isblock == true) {
140 5b4ee05e Ermal
					$isblock = false;
141 b37a2e8c Phil Davis
				}
142 5b4ee05e Ermal
			}
143
			/* Destination */
144
			if (trim($rule[$index]) == "host") {
145
				$index++;
146 b0ccc67b Phil Davis
				$tmprule .= "to {$rule[$index]} ";
147 5b4ee05e Ermal
				$index++;
148 b37a2e8c Phil Davis
				if ($isblock == true) {
149 5b4ee05e Ermal
					$isblock = false;
150 b37a2e8c Phil Davis
				}
151 5b4ee05e Ermal
			} else if (trim($rule[$index]) == "any") {
152
				$index++;
153 b0ccc67b Phil Davis
				$tmprule .= "to any";
154 5b4ee05e Ermal
			} else {
155 b0ccc67b Phil Davis
				$tmprule .= "to {$rule[$index]}";
156 5b4ee05e Ermal
				$index++;
157
				$netmask = cisco_to_cidr($rule[$index]);
158
				$tmprule .= "/{$netmask} ";
159
				$index++;
160 b37a2e8c Phil Davis
				if ($isblock == true) {
161 5b4ee05e Ermal
					$isblock = false;
162 b37a2e8c Phil Davis
				}
163 5b4ee05e Ermal
			}
164
165 b37a2e8c Phil Davis
			if ($isblock == true) {
166 5b4ee05e Ermal
				continue;
167 b37a2e8c Phil Davis
			}
168 5b4ee05e Ermal
169 b37a2e8c Phil Davis
			if ($dir == "in") {
170 5b4ee05e Ermal
				$inrules[$rindex] = $tmprule;
171 b37a2e8c Phil Davis
			} else if ($dir == "out") {
172 5b4ee05e Ermal
				$outrules[$rindex] = $tmprule;
173 b37a2e8c Phil Davis
			}
174 5b4ee05e Ermal
		}
175
176
177
		$state = "";
178 b37a2e8c Phil Davis
		if (!empty($outrules)) {
179 5b4ee05e Ermal
			$state = "no state";
180 b37a2e8c Phil Davis
		}
181 5b4ee05e Ermal
		ksort($inrules, SORT_NUMERIC);
182 b37a2e8c Phil Davis
		foreach ($inrules as $inrule) {
183 5b4ee05e Ermal
			$finalrules .= "{$inrule} {$state}\n";
184 b37a2e8c Phil Davis
		}
185 5b4ee05e Ermal
		if (!empty($outrules)) {
186
			ksort($outrules, SORT_NUMERIC);
187 b37a2e8c Phil Davis
			foreach ($outrules as $outrule) {
188 5b4ee05e Ermal
				$finalrules .= "{$outrule} {$state}\n";
189 b37a2e8c Phil Davis
			}
190 5b4ee05e Ermal
		}
191
	}
192
	return $finalrules;
193
}
194
195
$rules = parse_cisco_acl($attributes);
196
if (!empty($rules)) {
197 7b95ffdd Ermal
	$pid = posix_getpid();
198
	@file_put_contents("/tmp/ovpn_{$pid}{$common_name}.rules", $rules);
199 7b27b18b Renato Botelho
	mwexec("/sbin/pfctl -a " . escapeshellarg("openvpn/{$common_name}") . " -f {$g['tmp_path']}/ovpn_{$pid}" . escapeshellarg($common_name) . ".rules");
200 7b95ffdd Ermal
	@unlink("{$g['tmp_path']}/ovpn_{$pid}{$common_name}.rules");
201 5b4ee05e Ermal
}
202
203
?>