Project

General

Profile

Download (25.8 KB) Statistics
| Branch: | Tag: | Revision:
1 d2cfb7a4 Scott Ullrich
<?php
2 b46bfcf5 Bill Marquette
/* $Id$ */
3 5b237745 Scott Ullrich
/*
4
	firewall_aliases_edit.php
5 2e9ab96b Scott Ullrich
	Copyright (C) 2004 Scott Ullrich
6 09a68ea4 Phil Davis
	Copyright (C) 2009 Ermal Luçi
7 fff3d2b9 jim-p
	Copyright (C) 2010 Jim Pingle
8 ce77a9c4 Phil Davis
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
9 2e9ab96b Scott Ullrich
	All rights reserved.
10
11 bbd1f783 Phil Davis
	originally part of m0n0wall (http://m0n0.ch/wall)
12 5b237745 Scott Ullrich
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
13
	All rights reserved.
14 d2cfb7a4 Scott Ullrich
15 5b237745 Scott Ullrich
	Redistribution and use in source and binary forms, with or without
16
	modification, are permitted provided that the following conditions are met:
17 d2cfb7a4 Scott Ullrich
18 5b237745 Scott Ullrich
	1. Redistributions of source code must retain the above copyright notice,
19
	   this list of conditions and the following disclaimer.
20 d2cfb7a4 Scott Ullrich
21 5b237745 Scott Ullrich
	2. Redistributions in binary form must reproduce the above copyright
22
	   notice, this list of conditions and the following disclaimer in the
23
	   documentation and/or other materials provided with the distribution.
24 d2cfb7a4 Scott Ullrich
25 5b237745 Scott Ullrich
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
26
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
29
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
	POSSIBILITY OF SUCH DAMAGE.
35
*/
36 7ac5a4cb Scott Ullrich
/*
37
	pfSense_BUILDER_BINARIES:	/bin/rm	/bin/mkdir	/usr/bin/fetch
38
	pfSense_MODULE:	aliases
39
*/
40 5b237745 Scott Ullrich
41 6b07c15a Matthew Grooms
##|+PRIV
42
##|*IDENT=page-firewall-alias-edit
43
##|*NAME=Firewall: Alias: Edit page
44
##|*DESCR=Allow access to the 'Firewall: Alias: Edit' page.
45
##|*MATCH=firewall_aliases_edit.php*
46
##|-PRIV
47
48 5b237745 Scott Ullrich
require("guiconfig.inc");
49 7a927e67 Scott Ullrich
require_once("functions.inc");
50
require_once("filter.inc");
51
require_once("shaper.inc");
52 5b237745 Scott Ullrich
53 b13f7f80 Carlos Eduardo Ramos
$pgtitle = array(gettext("Firewall"),gettext("Aliases"),gettext("Edit"));
54
55 62424bdb Renato Botelho
$referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/firewall_aliases.php');
56
57 c48fdaa4 Renato Botelho
// Keywords not allowed in names
58
$reserved_keywords = array("all", "pass", "block", "out", "queue", "max", "min", "pptp", "pppoe", "L2TP", "OpenVPN", "IPsec");
59
60 24445691 Phil Davis
// Add all Load balance names to reserved_keywords
61 c48fdaa4 Renato Botelho
if (is_array($config['load_balancer']['lbpool']))
62
	foreach ($config['load_balancer']['lbpool'] as $lbpool)
63
		$reserved_keywords[] = $lbpool['name'];
64
65 7c9d8d71 Ermal Lu?i
$reserved_ifs = get_configured_interface_list(false, true);
66 c48fdaa4 Renato Botelho
$reserved_keywords = array_merge($reserved_keywords, $reserved_ifs, $reserved_table_names);
67 feb1953e Phil Davis
$max_alias_addresses = 5000;
68 7c9d8d71 Ermal Lu?i
69 5b237745 Scott Ullrich
if (!is_array($config['aliases']['alias']))
70
	$config['aliases']['alias'] = array();
71
$a_aliases = &$config['aliases']['alias'];
72 f29109d0 Renato Botelho
73 ac7f1763 Renato Botelho
$tab = $_REQUEST['tab'];
74
75 ed0b7949 Scott Ullrich
if($_POST)
76
	$origname = $_POST['origname'];
77
78
// Debugging
79 f5200c44 Scott Ullrich
if($debug)
80 552f5a6a Renato Botelho
	unlink_if_exists("{$g['tmp_path']}/alias_rename_log.txt");
81 ed0b7949 Scott Ullrich
82 5e34cdb2 Ermal Lu?i
function alias_same_type($name, $type) {
83
	global $config;
84 f29109d0 Renato Botelho
85 5e34cdb2 Ermal Lu?i
	foreach ($config['aliases']['alias'] as $alias) {
86
		if ($name == $alias['name']) {
87 d6c9ab97 Ermal Lu?i
			if (in_array($type, array("host", "network")) &&
88 5e34cdb2 Ermal Lu?i
				in_array($alias['type'], array("host", "network")))
89
				return true;
90
			if ($type  == $alias['type'])
91
				return true;
92
			else
93
				return false;
94
		}
95
	}
96
	return true;
97
}
98
99 e41ec584 Renato Botelho
if (is_numericint($_GET['id']))
100
	$id = $_GET['id'];
101
if (isset($_POST['id']) && is_numericint($_POST['id']))
102 5b237745 Scott Ullrich
	$id = $_POST['id'];
103
104
if (isset($id) && $a_aliases[$id]) {
105 ed0b7949 Scott Ullrich
	$original_alias_name = $a_aliases[$id]['name'];
106 5b237745 Scott Ullrich
	$pconfig['name'] = $a_aliases[$id]['name'];
107 ba393f6c Scott Dale
	$pconfig['detail'] = $a_aliases[$id]['detail'];
108
	$pconfig['address'] = $a_aliases[$id]['address'];
109 b4deddce Ermal Lu?i
	$pconfig['type'] = $a_aliases[$id]['type'];
110 ba393f6c Scott Dale
	$pconfig['descr'] = html_entity_decode($a_aliases[$id]['descr']);
111 e47c266d Scott Ullrich
112 dd042c51 Renato Botelho
	if(preg_match("/urltable/i", $a_aliases[$id]['type'])) {
113 c7de8be4 jim-p
		$pconfig['address'] = $a_aliases[$id]['url'];
114
		$pconfig['updatefreq'] = $a_aliases[$id]['updatefreq'];
115
	}
116 14726356 Sjon Hortensius
	if($a_aliases[$id]['aliasurl'] != "") {
117 c5eaef8e Renato Botelho
		if(is_array($a_aliases[$id]['aliasurl']))
118
			$pconfig['address'] = implode(" ", $a_aliases[$id]['aliasurl']);
119
		else
120 5a1eebc7 Scott Ullrich
			$pconfig['address'] = $a_aliases[$id]['aliasurl'];
121
	}
122 5b237745 Scott Ullrich
}
123
124
if ($_POST) {
125
	unset($input_errors);
126 24445691 Phil Davis
	$vertical_bar_err_text = gettext("Vertical bars (|) at start or end, or double in the middle of descriptions not allowed. Descriptions have been cleaned. Check and save again.");
127 5b237745 Scott Ullrich
128
	/* input validation */
129 0cd7ed19 Scott Ullrich
130 69d2ad77 Erik Fonnesbeck
	$reqdfields = explode(" ", "name");
131 bd413d76 Renato Botelho
	$reqdfieldsn = array(gettext("Name"));
132 69d2ad77 Erik Fonnesbeck
133 1e9b4611 Renato Botelho
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
134 69d2ad77 Erik Fonnesbeck
135 0df6adf8 Bill Marquette
	$x = is_validaliasname($_POST['name']);
136
	if (!isset($x)) {
137 24148939 Carlos Eduardo Ramos
		$input_errors[] = gettext("Reserved word used for alias name.");
138 3deb92f7 Renato Botelho
	} else if ($_POST['type'] == "port" && (getservbyname($_POST['name'], "tcp") || getservbyname($_POST['name'], "udp"))) {
139 bd413d76 Renato Botelho
		$input_errors[] = gettext("Reserved word used for alias name.");
140 3deb92f7 Renato Botelho
	} else {
141
		if (is_validaliasname($_POST['name']) == false)
142 dc4a8b9e Chris Buechler
			$input_errors[] = gettext("The alias name must be less than 32 characters long, may not consist of only numbers, and may only contain the following characters") . " a-z, A-Z, 0-9, _.";
143 3deb92f7 Renato Botelho
	}
144 5b237745 Scott Ullrich
	/* check for name conflicts */
145 6c33fb4b Ermal
	if (empty($a_aliases[$id])) {
146 6b487ec6 Ermal
		foreach ($a_aliases as $alias) {
147
			if ($alias['name'] == $_POST['name']) {
148 24148939 Carlos Eduardo Ramos
				$input_errors[] = gettext("An alias with this name already exists.");
149 6b487ec6 Ermal
				break;
150
			}
151 5b237745 Scott Ullrich
		}
152
	}
153 5a1eebc7 Scott Ullrich
154 f76a479d sullrich
	/* Check for reserved keyword names */
155 f29109d0 Renato Botelho
	foreach($reserved_keywords as $rk)
156 f76a479d sullrich
		if($rk == $_POST['name'])
157 24148939 Carlos Eduardo Ramos
			$input_errors[] = sprintf(gettext("Cannot use a reserved keyword as alias name %s"), $rk);
158 f76a479d sullrich
159 cfa466bb Scott Ullrich
	/* check for name interface description conflicts */
160
	foreach($config['interfaces'] as $interface) {
161
		if($interface['descr'] == $_POST['name']) {
162 24148939 Carlos Eduardo Ramos
			$input_errors[] = gettext("An interface description with this name already exists.");
163 5a1eebc7 Scott Ullrich
			break;
164 cfa466bb Scott Ullrich
		}
165 5a1eebc7 Scott Ullrich
	}
166 f29109d0 Renato Botelho
167 ba393f6c Scott Dale
	$alias = array();
168 6c33fb4b Ermal
	$address = array();
169
	$final_address_details = array();
170 ba393f6c Scott Dale
	$alias['name'] = $_POST['name'];
171 c7de8be4 jim-p
172 dd042c51 Renato Botelho
	if (preg_match("/urltable/i", $_POST['type'])) {
173 c7de8be4 jim-p
		$address = "";
174
175 24445691 Phil Davis
		/* item is a url table type */
176 14726356 Sjon Hortensius
		if ($_POST['address'][0]) {
177 c7de8be4 jim-p
			/* fetch down and add in */
178 14726356 Sjon Hortensius
			$_POST['address'][0] = trim($_POST['address'][0]);
179
			$address[] = $_POST['address'][0];
180
			$alias['url'] = $_POST['address'][0];
181
			$alias['updatefreq'] = $_POST['frequency'][0] ? $_POST['frequency'][0] : 7;
182 c7de8be4 jim-p
			if (!is_URL($alias['url']) || empty($alias['url'])) {
183 24148939 Carlos Eduardo Ramos
				$input_errors[] = gettext("You must provide a valid URL.");
184 c7de8be4 jim-p
			} elseif (! process_alias_urltable($alias['name'], $alias['url'], 0, true)) {
185 24148939 Carlos Eduardo Ramos
				$input_errors[] = gettext("Unable to fetch usable data.");
186 c7de8be4 jim-p
			}
187 14726356 Sjon Hortensius
			if ($_POST["detail"][0] != "") {
188
				if ((strpos($_POST["detail"][0], "||") === false) && (substr($_POST["detail"][0], 0, 1) != "|") && (substr($_POST["detail"][0], -1, 1) != "|")) {
189
					$final_address_details[] = $_POST["detail"][0];
190 24445691 Phil Davis
				} else {
191
					/* Remove leading and trailing vertical bars and replace multiple vertical bars with single, */
192
					/* and put in the output array so the text is at least redisplayed for the user. */
193 14726356 Sjon Hortensius
					$final_address_details[] = preg_replace('/\|\|+/', '|', trim($_POST["detail"][0], "|"));
194 24445691 Phil Davis
					$input_errors[] = $vertical_bar_err_text;
195
				}
196
			} else
197 0b9e4e8f Renato Botelho
				$final_address_details[] = sprintf(gettext("Entry added %s"), date('r'));
198 c7de8be4 jim-p
		}
199 079d1952 Renato Botelho
	} else if ($_POST['type'] == "url" || $_POST['type'] == "url_ports") {
200 24445691 Phil Davis
		$desc_fmt_err_found = false;
201 ba393f6c Scott Dale
202
		/* item is a url type */
203 14726356 Sjon Hortensius
			foreach ($_POST['address'] as $idx => $post_address) {
204 ba393f6c Scott Dale
				/* fetch down and add in */
205 7c872d3b Scott Ullrich
				$temp_filename = tempnam("{$g['tmp_path']}/", "alias_import");
206 552f5a6a Renato Botelho
				unlink_if_exists($temp_filename);
207 76590ffe Renato Botelho
				$verify_ssl = isset($config['system']['checkaliasesurlcert']);
208 d31ca336 Renato Botelho
				mkdir($temp_filename);
209 14726356 Sjon Hortensius
				download_file($post_address, $temp_filename . "/aliases", $verify_ssl);
210 76590ffe Renato Botelho
211 ba393f6c Scott Dale
				/* if the item is tar gzipped then extract */
212 14726356 Sjon Hortensius
				if(stristr($post_address, ".tgz"))
213 ba393f6c Scott Dale
					process_alias_tgz($temp_filename);
214 14726356 Sjon Hortensius
				else if(stristr($post_address, ".zip"))
215 86ffa26d Renato Botelho
					process_alias_unzip($temp_filename);
216 ae5f96c8 Renato Botelho
217
				if (!isset($alias['aliasurl']))
218
					$alias['aliasurl'] = array();
219
220 14726356 Sjon Hortensius
				$alias['aliasurl'][] = $post_address;
221
				if ($_POST['detail'][$idx] != "") {
222
					if ((strpos($_POST['detail'][$idx], "||") === false) && (substr($_POST['detail'][$idx], 0, 1) != "|") && (substr($_POST['detail'][$idx], -1, 1) != "|")) {
223
						$final_address_details[] = $_POST['detail'][$idx];
224 24445691 Phil Davis
					} else {
225
						/* Remove leading and trailing vertical bars and replace multiple vertical bars with single, */
226
						/* and put in the output array so the text is at least redisplayed for the user. */
227 14726356 Sjon Hortensius
						$final_address_details[] = preg_replace('/\|\|+/', '|', trim($_POST['detail'][$idx], "|"));
228 24445691 Phil Davis
						if (!$desc_fmt_err_found) {
229
							$input_errors[] = $vertical_bar_err_text;
230
							$desc_fmt_err_found = true;
231
						}
232
					}
233
				} else
234 ae5f96c8 Renato Botelho
					$final_address_details[] = sprintf(gettext("Entry added %s"), date('r'));
235
236 ba393f6c Scott Dale
				if(file_exists("{$temp_filename}/aliases")) {
237 6d1907a3 Renato Botelho
					$address = parse_aliases_file("{$temp_filename}/aliases", $_POST['type'], 3000);
238
					if($address == null) {
239 ba393f6c Scott Dale
						/* nothing was found */
240 14726356 Sjon Hortensius
						$input_errors[] = sprintf(gettext("You must provide a valid URL. Could not fetch usable data from '%s'."), $post_address);
241 5a1eebc7 Scott Ullrich
					}
242 d31ca336 Renato Botelho
					mwexec("/bin/rm -rf " . escapeshellarg($temp_filename));
243 ba393f6c Scott Dale
				} else {
244 14726356 Sjon Hortensius
					$input_errors[] = sprintf(gettext("URL '%s' is not valid."), $post_address);
245 5a1eebc7 Scott Ullrich
				}
246
			}
247 24445691 Phil Davis
		unset($desc_fmt_err_found);
248 079d1952 Renato Botelho
		if ($_POST['type'] == "url_ports")
249
			$address = group_ports($address);
250 ba393f6c Scott Dale
	} else {
251
		/* item is a normal alias type */
252 5e34cdb2 Ermal Lu?i
		$wrongaliases = "";
253 24445691 Phil Davis
		$desc_fmt_err_found = false;
254 feb1953e Phil Davis
		$alias_address_count = 0;
255 055a43d2 Phil Davis
256 14726356 Sjon Hortensius
		// First trim and expand the input data.
257 055a43d2 Phil Davis
		// Users can paste strings like "10.1.2.0/24 10.3.0.0/16 9.10.11.0/24" into an address box.
258
		// They can also put an IP range.
259
		// This loop expands out that stuff so it can easily be validated.
260 14726356 Sjon Hortensius
			foreach ($_POST['address'] as $idx => $post_address) {
261
				if ($post_address != "") {
262
					if ((strpos($post_address, "||") === false) && (substr($post_address, 0, 1) != "|") && (substr($post_address, -1, 1) != "|")) {
263
						$detail_text = $post_address;
264 24445691 Phil Davis
					} else {
265
						/* Remove leading and trailing vertical bars and replace multiple vertical bars with single, */
266
						/* and put in the output array so the text is at least redisplayed for the user. */
267 14726356 Sjon Hortensius
						$detail_text = preg_replace('/\|\|+/', '|', trim($post_address, "|"));
268 24445691 Phil Davis
						if (!$desc_fmt_err_found) {
269
							$input_errors[] = $vertical_bar_err_text;
270
							$desc_fmt_err_found = true;
271
						}
272
					}
273 6b18c66b Phil Davis
				} else {
274 055a43d2 Phil Davis
					$detail_text = sprintf(gettext("Entry added %s"), date('r'));
275
				}
276 14726356 Sjon Hortensius
				$address_items = explode(" ", trim($post_address));
277 055a43d2 Phil Davis
				foreach ($address_items as $address_item) {
278 feb1953e Phil Davis
					$iprange_type = is_iprange($address_item);
279
					if ($iprange_type == 4) {
280 055a43d2 Phil Davis
						list($startip, $endip) = explode('-', $address_item);
281 feb1953e Phil Davis
						if ($_POST['type'] == "network") {
282
							// For network type aliases, expand an IPv4 range into an array of subnets.
283
							$rangesubnets = ip_range_to_subnet_array($startip, $endip);
284
							foreach ($rangesubnets as $rangesubnet) {
285
								if ($alias_address_count > $max_alias_addresses) {
286
									break;
287
								}
288
								list($address_part, $subnet_part) = explode("/", $rangesubnet);
289
								$input_addresses[] = $address_part;
290
								$input_address_subnet[] = $subnet_part;
291
								$final_address_details[] = $detail_text;
292
								$alias_address_count++;
293
							}
294
						} else {
295
							// For host type aliases, expand an IPv4 range into a list of individual IPv4 addresses.
296
							$rangeaddresses = ip_range_to_address_array($startip, $endip, $max_alias_addresses - $alias_address_count);
297
							if (is_array($rangeaddresses)) {
298
								foreach ($rangeaddresses as $rangeaddress) {
299
									$input_addresses[] = $rangeaddress;
300
									$input_address_subnet[] = "";
301
									$final_address_details[] = $detail_text;
302
									$alias_address_count++;
303
								}
304
							} else {
305
								$input_errors[] = sprintf(gettext('Range is too large to expand into individual host IP addresses (%s)'), $address_item);
306
								$input_errors[] = sprintf(gettext('The maximum number of entries in an alias is %s'), $max_alias_addresses);
307
								// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
308
								$input_addresses[] = $address_item;
309
								$input_address_subnet[] = "";
310
								$final_address_details[] = $detail_text;
311
							}
312 055a43d2 Phil Davis
						}
313 feb1953e Phil Davis
					} else if ($iprange_type == 6) {
314
						$input_errors[] = sprintf(gettext('IPv6 address ranges are not supported (%s)'), $address_item);
315
						// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
316
						$input_addresses[] = $address_item;
317
						$input_address_subnet[] = "";
318 055a43d2 Phil Davis
						$final_address_details[] = $detail_text;
319 feb1953e Phil Davis
					} else {
320
						$subnet_type = is_subnet($address_item);
321
						if (($_POST['type'] == "host") && $subnet_type) {
322
							if ($subnet_type == 4) {
323
								// For host type aliases, if the user enters an IPv4 subnet, expand it into a list of individual IPv4 addresses.
324
								if (subnet_size($address_item) <= ($max_alias_addresses - $alias_address_count)) {
325
									$rangeaddresses = subnetv4_expand($address_item);
326
									foreach ($rangeaddresses as $rangeaddress) {
327
										$input_addresses[] = $rangeaddress;
328
										$input_address_subnet[] = "";
329
										$final_address_details[] = $detail_text;
330
										$alias_address_count++;
331
									}
332
								} else {
333
									$input_errors[] = sprintf(gettext('Subnet is too large to expand into individual host IP addresses (%s)'), $address_item);
334
									$input_errors[] = sprintf(gettext('The maximum number of entries in an alias is %s'), $max_alias_addresses);
335
									// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
336
									$input_addresses[] = $address_item;
337
									$input_address_subnet[] = "";
338
									$final_address_details[] = $detail_text;
339
								}
340
							} else {
341
								$input_errors[] = sprintf(gettext('IPv6 subnets are not supported in host aliases (%s)'), $address_item);
342
								// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
343
								$input_addresses[] = $address_item;
344
								$input_address_subnet[] = "";
345
								$final_address_details[] = $detail_text;
346
							}
347
						} else {
348
							list($address_part, $subnet_part) = explode("/", $address_item);
349
							if (!empty($subnet_part)) {
350
								if (is_subnet($address_item)) {
351
									$input_addresses[] = $address_part;
352
									$input_address_subnet[] = $subnet_part;
353
								} else {
354
									// The user typed something like "1.2.3.444/24" or "1.2.3.0/36" or similar rubbish.
355
									// Feed it through without splitting it apart, then it will be caught by the validation loop below.
356
									$input_addresses[] = $address_item;
357
									$input_address_subnet[] = "";
358
								}
359
							} else {
360
								$input_addresses[] = $address_part;
361 14726356 Sjon Hortensius
								$input_address_subnet[] = $_POST["address_subnet"][$idx];
362 feb1953e Phil Davis
							}
363
							$final_address_details[] = $detail_text;
364
							$alias_address_count++;
365
						}
366
					}
367
					if ($alias_address_count > $max_alias_addresses) {
368
						$input_errors[] = sprintf(gettext('The maximum number of entries in an alias has been exceeded (%s)'), $max_alias_addresses);
369
						break;
370 055a43d2 Phil Davis
					}
371
				}
372
			}
373
374
		// Validate the input data expanded above.
375
		foreach($input_addresses as $idx => $input_address) {
376
			if (is_alias($input_address)) {
377
				if (!alias_same_type($input_address, $_POST['type']))
378
					// But alias type network can include alias type urltable. Feature#1603.
379
					if (!($_POST['type'] == 'network' &&
380
						  preg_match("/urltable/i", alias_get_type($input_address))))
381
						$wrongaliases .= " " . $input_address;
382
			} else if ($_POST['type'] == "port") {
383
				if (!is_port($input_address) && !is_portrange($input_address))
384
					$input_errors[] = $input_address . " " . gettext("is not a valid port or alias.");
385
			} else if ($_POST['type'] == "host" || $_POST['type'] == "network") {
386 14726356 Sjon Hortensius
				if (is_subnet($input_address) ||
387 055a43d2 Phil Davis
					(!is_ipaddr($input_address) && !is_hostname($input_address)))
388
					$input_errors[] = sprintf(gettext('%1$s is not a valid %2$s address, FQDN or alias.'), $input_address, $_POST['type']);
389
			}
390
			$tmpaddress = $input_address;
391 14726356 Sjon Hortensius
			if ($_POST['type'] != "host" && is_ipaddr($input_address) && $input_address_subnet[$idx] != "") {
392 055a43d2 Phil Davis
				if (!is_subnet($input_address . "/" . $input_address_subnet[$idx]))
393
					$input_errors[] = sprintf(gettext('%s/%s is not a valid subnet.'), $input_address, $input_address_subnet[$idx]);
394
				else
395
					$tmpaddress .= "/" . $input_address_subnet[$idx];
396 5e34cdb2 Ermal Lu?i
			}
397 055a43d2 Phil Davis
			$address[] = $tmpaddress;
398 d2cfb7a4 Scott Ullrich
		}
399 24445691 Phil Davis
		unset($desc_fmt_err_found);
400 14726356 Sjon Hortensius
		if ($wrongaliases != "")
401 bcc8d8a3 Erik Fonnesbeck
			$input_errors[] = sprintf(gettext('The alias(es): %s cannot be nested because they are not of the same type.'), $wrongaliases);
402 ba393f6c Scott Dale
	}
403 d2cfb7a4 Scott Ullrich
404 24445691 Phil Davis
	unset($vertical_bar_err_text);
405
406 f29109d0 Renato Botelho
	// Allow extending of the firewall edit page and include custom input validation
407 439cc13f Scott Ullrich
	pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/input_validation");
408
409 ba393f6c Scott Dale
	if (!$input_errors) {
410 c7de8be4 jim-p
		$alias['address'] = is_array($address) ? implode(" ", $address) : $address;
411 d865241e jim-p
		$alias['descr'] = $_POST['descr'];
412 ba393f6c Scott Dale
		$alias['type'] = $_POST['type'];
413 6c33fb4b Ermal
		$alias['detail'] = implode("||", $final_address_details);
414 d2cfb7a4 Scott Ullrich
415 ed0b7949 Scott Ullrich
		/*   Check to see if alias name needs to be
416
		 *   renamed on referenced rules and such
417
		 */
418 14726356 Sjon Hortensius
		if ($_POST['name'] != $_POST['origname']) {
419 ed0b7949 Scott Ullrich
			// Firewall rules
420 f1ac1733 Erik Fonnesbeck
			update_alias_names_upon_change(array('filter', 'rule'), array('source', 'address'), $_POST['name'], $origname);
421
			update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
422
			update_alias_names_upon_change(array('filter', 'rule'), array('source', 'port'), $_POST['name'], $origname);
423
			update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'port'), $_POST['name'], $origname);
424 ed0b7949 Scott Ullrich
			// NAT Rules
425 f1ac1733 Erik Fonnesbeck
			update_alias_names_upon_change(array('nat', 'rule'), array('source', 'address'), $_POST['name'], $origname);
426
			update_alias_names_upon_change(array('nat', 'rule'), array('source', 'port'), $_POST['name'], $origname);
427
			update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
428
			update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'port'), $_POST['name'], $origname);
429
			update_alias_names_upon_change(array('nat', 'rule'), array('target'), $_POST['name'], $origname);
430
			update_alias_names_upon_change(array('nat', 'rule'), array('local-port'), $_POST['name'], $origname);
431 b43b7613 Erik Fonnesbeck
			// NAT 1:1 Rules
432
			//update_alias_names_upon_change(array('nat', 'onetoone'), array('external'), $_POST['name'], $origname);
433
			//update_alias_names_upon_change(array('nat', 'onetoone'), array('source', 'address'), $_POST['name'], $origname);
434
			update_alias_names_upon_change(array('nat', 'onetoone'), array('destination', 'address'), $_POST['name'], $origname);
435
			// NAT Outbound Rules
436
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('source', 'network'), $_POST['name'], $origname);
437 ca640261 Erik Fonnesbeck
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('sourceport'), $_POST['name'], $origname);
438 b43b7613 Erik Fonnesbeck
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
439 ca640261 Erik Fonnesbeck
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('dstport'), $_POST['name'], $origname);
440 b43b7613 Erik Fonnesbeck
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('target'), $_POST['name'], $origname);
441 f43ba926 Scott Ullrich
			// Alias in an alias
442 f1ac1733 Erik Fonnesbeck
			update_alias_names_upon_change(array('aliases', 'alias'), array('address'), $_POST['name'], $origname);
443 ed0b7949 Scott Ullrich
		}
444
445 b22bf161 Scott Ullrich
		pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/pre_write_config");
446
447 171aa30d Ermal Lu?i
		if (isset($id) && $a_aliases[$id]) {
448 14726356 Sjon Hortensius
			if ($a_aliases[$id]['name'] != $alias['name']) {
449 171aa30d Ermal Lu?i
				foreach ($a_aliases as $aliasid => $aliasd) {
450 14726356 Sjon Hortensius
					if ($aliasd['address'] != "") {
451 96b4269c Ermal Lu?i
						$tmpdirty = false;
452 16f78ff0 Ermal Lu?i
						$tmpaddr = explode(" ", $aliasd['address']);
453
						foreach ($tmpaddr as $tmpidx => $tmpalias) {
454 96b4269c Ermal Lu?i
							if ($tmpalias == $a_aliases[$id]['name']) {
455 16f78ff0 Ermal Lu?i
								$tmpaddr[$tmpidx] = $alias['name'];
456 96b4269c Ermal Lu?i
								$tmpdirty = true;
457
							}
458 16f78ff0 Ermal Lu?i
						}
459 96b4269c Ermal Lu?i
						if ($tmpdirty == true)
460
							$a_aliases[$aliasid]['address'] = implode(" ", $tmpaddr);
461 16f78ff0 Ermal Lu?i
					}
462 171aa30d Ermal Lu?i
				}
463
			}
464 ba393f6c Scott Dale
			$a_aliases[$id] = $alias;
465 171aa30d Ermal Lu?i
		} else
466 ba393f6c Scott Dale
			$a_aliases[] = $alias;
467 a18b6b97 Scott Ullrich
468 974cbfe0 Ermal Lu?i
		// Sort list
469
		$a_aliases = msort($a_aliases, "name");
470
471 3a343d73 jim-p
		if (write_config())
472
			mark_subsystem_dirty('aliases');
473 d2cfb7a4 Scott Ullrich
474 ac7f1763 Renato Botelho
		if(!empty($tab))
475
			header("Location: firewall_aliases.php?tab=" . htmlspecialchars ($tab));
476 a5416de2 Warren Baker
		else
477
			header("Location: firewall_aliases.php");
478
		exit;
479 ba393f6c Scott Dale
	}
480
	//we received input errors, copy data to prevent retype
481
	else
482
	{
483 c7de8be4 jim-p
		$pconfig['name'] = $_POST['name'];
484 d865241e jim-p
		$pconfig['descr'] = $_POST['descr'];
485 079d1952 Renato Botelho
		if (($_POST['type'] == 'url') || ($_POST['type'] == 'url_ports'))
486 6a45942f Renato Botelho
			$pconfig['address'] = implode(" ", $alias['aliasurl']);
487
		else
488
			$pconfig['address'] = implode(" ", $address);
489 ba393f6c Scott Dale
		$pconfig['type'] = $_POST['type'];
490 6c33fb4b Ermal
		$pconfig['detail'] = implode("||", $final_address_details);
491 5b237745 Scott Ullrich
	}
492
}
493 da7ae7ef Bill Marquette
494
include("head.inc");
495
496 bbd1f783 Phil Davis
$network_str = gettext("Network or FQDN");
497 5a1eebc7 Scott Ullrich
$networks_str = gettext("Network(s)");
498
$cidr_str = gettext("CIDR");
499
$description_str = gettext("Description");
500
$hosts_str = gettext("Host(s)");
501 bbd1f783 Phil Davis
$ip_str = gettext("IP or FQDN");
502 5a1eebc7 Scott Ullrich
$ports_str = gettext("Port(s)");
503
$port_str = gettext("Port");
504 079d1952 Renato Botelho
$url_str = gettext("URL (IPs)");
505
$url_ports_str = gettext("URL (Ports)");
506 dd042c51 Renato Botelho
$urltable_str = gettext("URL Table (IPs)");
507
$urltable_ports_str = gettext("URL Table (Ports)");
508 2b6e6fee Renato Botelho
$update_freq_str = gettext("Update Freq. (days)");
509 5a1eebc7 Scott Ullrich
510 14726356 Sjon Hortensius
$help = array(
511
	'network' => "Networks are specified in CIDR format.  Select the CIDR mask that pertains to each entry. /32 specifies a single IPv4 host, /128 specifies a single IPv6 host, /24 specifies 255.255.255.0, /64 specifies a normal IPv6 network, etc. Hostnames (FQDNs) may also be specified, using a /32 mask for IPv4 or /128 for IPv6. You may also enter an IP range such as 192.168.1.1-192.168.1.254 and a list of CIDR networks will be derived to fill the range.",
512
	'host' => "Enter as many hosts as you would like.  Hosts must be specified by their IP address or fully qualified domain name (FQDN). FQDN hostnames are periodically re-resolved and updated. If multiple IPs are returned by a DNS query, all are used. You may also enter an IP range such as 192.168.1.1-192.168.1.10 or a small subnet such as 192.168.1.16/28 and a list of individual IP addresses will be generated.",
513
	'port' => "Enter as many ports as you wish.  Port ranges can be expressed by separating with a colon.",
514
	'url' => "Enter as many URLs as you wish. After saving we will download the URL and import the items into the alias. Use only with small sets of IP addresses (less than 3000).",
515
	'url_ports' => "Enter as many URLs as you wish. After saving we will download the URL and import the items into the alias. Use only with small sets of Ports (less than 3000).",
516
	'urltable' => "Enter a single URL containing a large number of IPs and/or Subnets. After saving we will download the URL and create a table file containing these addresses. This will work with large numbers of addresses (30,000+) or small numbers.",
517
	'urltable_ports' => "Enter a single URL containing a list of Port numbers and/or Port ranges. After saving we will download the URL.",
518
);
519
520
$types = array(
521
	'host' => 'Host(s)',
522
	'network' => 'Network(s)',
523
	'port' => 'Port(s)',
524
	'url' => 'URL (IPs)',
525
	'url_ports' => 'URL (Ports)',
526
	'urltable' => 'URL Table (IPs)',
527
	'urltable_ports' => 'URL Table (Ports)',
528
);
529 d2cfb7a4 Scott Ullrich
530 ac7f1763 Renato Botelho
if (empty($tab)) {
531 079d1952 Renato Botelho
	if (preg_match("/url/i", $pconfig['type']))
532 ac7f1763 Renato Botelho
		$tab = 'url';
533
	else if ($pconfig['type'] == 'host')
534
		$tab = 'ip';
535
	else
536
		$tab = $pconfig['type'];
537
}
538 14726356 Sjon Hortensius
539
if ($input_errors)
540
	print_input_errors($input_errors);
541
542
require('classes/Form.class.php');
543
$form = new Form;
544
545
$form->addGlobal(new Form_Input(
546
	'tab',
547
	null,
548
	'hidden',
549
	$tab
550
));
551
$form->addGlobal(new Form_Input(
552
	'origname',
553
	null,
554
	'hidden',
555
	$pconfig['name']
556
));
557
558
if (isset($id) && $a_aliases[$id])
559
{
560
	$form->addGlobal(new Form_Input(
561
		'id',
562
		null,
563
		'hidden',
564
		$id
565
	));
566
}
567
568
$section = new Form_Section('Properties');
569
$section->addInput(new Form_Input(
570
	'name',
571
	'Name',
572
	'text',
573
	$pconfig['name']
574
))->setPattern('[a-zA-Z0-9_]+')->setHelp('The name of the alias may only consist '.
575
	'of the characters "a-z, A-Z, 0-9 and _".');
576
577
$section->addInput(new Form_Input(
578
	'descr',
579
	'Description',
580
	'text',
581
	$pconfig['descr']
582
))->setHelp('You may enter a description here for your reference (not parsed).');
583
584
$section->addInput(new Form_Select(
585
	'type',
586
	'Type',
587
	isset($pconfig['type']) ? $pconfig['type'] : $tab,
588
	$types
589 44d906ca Sjon Hortensius
))->toggles();
590 14726356 Sjon Hortensius
591
$form->add($section);
592
593
foreach ($types as $type => $typeName)
594
{
595
	$section = new Form_Section('Details for '. $typeName);
596
	$section->addClass('toggle-'.$type.' collapse');
597
598
	// Texts are rather long; don't repeat for every input
599
	$section->addInput(new Form_StaticText('Help', $help[$type]));
600
601
	// Only include values for the correct type
602
	if (isset($pconfig['type']) && $type == $pconfig['type'])
603
	{
604
		$addresses = explode(' ', $pconfig['address']);
605
		$details = explode('||', $pconfig['detail']);
606
	}
607
	else
608
	{
609
		// When creating a new entry show at lease one input
610
		$addresses = array('');
611
		$details = array();
612 4dfd930e Darren Embry
	}
613 0cea9a23 Ermal Lu?i
614 14726356 Sjon Hortensius
	foreach ($addresses as $idx => $address)
615
	{
616
		$address_subnet = '';
617
		if (($pconfig['type'] != 'host') && is_subnet($address))
618
			list($address, $address_subnet) = explode('/', $address);
619
620
		if (substr($type, 0, 3) == 'url')
621
		{
622
			$group = new Form_Group('URL to download');
623
624
			$group->add(new Form_Input(
625
				'address',
626
				'URL to download',
627
				'url',
628
				$address
629
			));
630
631
			if (in_array($type, ['urltable', 'urltable_ports']))
632
			{
633
				$group->add(new Form_Input(
634
					'frequency',
635
					'Update frequency (days)',
636
					'number',
637
					$address_subnet,
638
					['min' => 1]
639
				));
640
			}
641
		}
642
		else
643
		{
644
			$group = new Form_Group('IP or FQDN');
645
646
			$group->add(new Form_IpAddress(
647
				'address',
648
				'IP or FQDN',
649
				$address
650
			))->addMask('address_subnet', $address_subnet);
651
652
			$group->add(new Form_Input(
653
				'detail',
654
				'Description (not parsed)',
655
				'text',
656
				$details[$idx]
657
			));
658
		}
659
660
		$group->enableDuplication();
661
		$section->add($group);
662
	}
663
664
	$form->add($section);
665
}
666
667
print $form;
668 5a1eebc7 Scott Ullrich
669 3c128b8c Sjon Hortensius
include("foot.inc");