Project

General

Profile

Download (37.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	firewall_aliases_edit.php
5
	Copyright (C) 2004 Scott Ullrich
6
	Copyright (C) 2009 Ermal Luçi
7
	Copyright (C) 2010 Jim Pingle
8
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
9
	All rights reserved.
10

    
11
	originally part of m0n0wall (http://m0n0.ch/wall)
12
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
13
	All rights reserved.
14

    
15
	Redistribution and use in source and binary forms, with or without
16
	modification, are permitted provided that the following conditions are met:
17

    
18
	1. Redistributions of source code must retain the above copyright notice,
19
	   this list of conditions and the following disclaimer.
20

    
21
	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

    
25
	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
/*
37
	pfSense_BUILDER_BINARIES:	/bin/rm	/bin/mkdir	/usr/bin/fetch
38
	pfSense_MODULE:	aliases
39
*/
40

    
41
##|+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
require("guiconfig.inc");
49
require_once("functions.inc");
50
require_once("filter.inc");
51
require_once("shaper.inc");
52

    
53
$pgtitle = array(gettext("Firewall"),gettext("Aliases"),gettext("Edit"));
54

    
55
$referer = (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '/firewall_aliases.php');
56

    
57
// Keywords not allowed in names
58
$reserved_keywords = array("all", "pass", "block", "out", "queue", "max", "min", "pptp", "pppoe", "L2TP", "OpenVPN", "IPsec");
59

    
60
// Add all Load balance names to reserved_keywords
61
if (is_array($config['load_balancer']['lbpool']))
62
	foreach ($config['load_balancer']['lbpool'] as $lbpool)
63
		$reserved_keywords[] = $lbpool['name'];
64

    
65
$reserved_ifs = get_configured_interface_list(false, true);
66
$reserved_keywords = array_merge($reserved_keywords, $reserved_ifs, $reserved_table_names);
67
$max_alias_addresses = 5000;
68

    
69
if (!is_array($config['aliases']['alias']))
70
	$config['aliases']['alias'] = array();
71
$a_aliases = &$config['aliases']['alias'];
72

    
73
$tab = $_REQUEST['tab'];
74

    
75
if($_POST)
76
	$origname = $_POST['origname'];
77

    
78
// Debugging
79
if($debug)
80
	unlink_if_exists("{$g['tmp_path']}/alias_rename_log.txt");
81

    
82
function alias_same_type($name, $type) {
83
	global $config;
84

    
85
	foreach ($config['aliases']['alias'] as $alias) {
86
		if ($name == $alias['name']) {
87
			if (in_array($type, array("host", "network")) &&
88
				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
if (is_numericint($_GET['id']))
100
	$id = $_GET['id'];
101
if (isset($_POST['id']) && is_numericint($_POST['id']))
102
	$id = $_POST['id'];
103

    
104
if (isset($id) && $a_aliases[$id]) {
105
	$original_alias_name = $a_aliases[$id]['name'];
106
	$pconfig['name'] = $a_aliases[$id]['name'];
107
	$pconfig['detail'] = $a_aliases[$id]['detail'];
108
	$pconfig['address'] = $a_aliases[$id]['address'];
109
	$pconfig['type'] = $a_aliases[$id]['type'];
110
	$pconfig['descr'] = html_entity_decode($a_aliases[$id]['descr']);
111

    
112
	if(preg_match("/urltable/i", $a_aliases[$id]['type'])) {
113
		$pconfig['address'] = $a_aliases[$id]['url'];
114
		$pconfig['updatefreq'] = $a_aliases[$id]['updatefreq'];
115
	}
116
	if($a_aliases[$id]['aliasurl'] <> "") {
117
		if(is_array($a_aliases[$id]['aliasurl']))
118
			$pconfig['address'] = implode(" ", $a_aliases[$id]['aliasurl']);
119
		else
120
			$pconfig['address'] = $a_aliases[$id]['aliasurl'];
121
	}
122
}
123

    
124
if ($_POST) {
125
	unset($input_errors);
126
	$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

    
128
	/* input validation */
129

    
130
	$reqdfields = explode(" ", "name");
131
	$reqdfieldsn = array(gettext("Name"));
132

    
133
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
134

    
135
	$x = is_validaliasname($_POST['name']);
136
	if (!isset($x)) {
137
		$input_errors[] = gettext("Reserved word used for alias name.");
138
	} else if ($_POST['type'] == "port" && (getservbyname($_POST['name'], "tcp") || getservbyname($_POST['name'], "udp"))) {
139
		$input_errors[] = gettext("Reserved word used for alias name.");
140
	} else {
141
		if (is_validaliasname($_POST['name']) == false)
142
			$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
	}
144
	/* check for name conflicts */
145
	if (empty($a_aliases[$id])) {
146
		foreach ($a_aliases as $alias) {
147
			if ($alias['name'] == $_POST['name']) {
148
				$input_errors[] = gettext("An alias with this name already exists.");
149
				break;
150
			}
151
		}
152
	}
153

    
154
	/* Check for reserved keyword names */
155
	foreach($reserved_keywords as $rk)
156
		if($rk == $_POST['name'])
157
			$input_errors[] = sprintf(gettext("Cannot use a reserved keyword as alias name %s"), $rk);
158

    
159
	/* check for name interface description conflicts */
160
	foreach($config['interfaces'] as $interface) {
161
		if($interface['descr'] == $_POST['name']) {
162
			$input_errors[] = gettext("An interface description with this name already exists.");
163
			break;
164
		}
165
	}
166

    
167
	$alias = array();
168
	$address = array();
169
	$final_address_details = array();
170
	$alias['name'] = $_POST['name'];
171

    
172
	if (preg_match("/urltable/i", $_POST['type'])) {
173
		$address = "";
174

    
175
		/* item is a url table type */
176
		if ($_POST['address0']) {
177
			/* fetch down and add in */
178
			$_POST['address0'] = trim($_POST['address0']);
179
			$address[] = $_POST['address0'];
180
			$alias['url'] = $_POST['address0'];
181
			$alias['updatefreq'] = $_POST['address_subnet0'] ? $_POST['address_subnet0'] : 7;
182
			if (!is_URL($alias['url']) || empty($alias['url'])) {
183
				$input_errors[] = gettext("You must provide a valid URL.");
184
			} elseif (! process_alias_urltable($alias['name'], $alias['url'], 0, true)) {
185
				$input_errors[] = gettext("Unable to fetch usable data.");
186
			}
187
			if ($_POST["detail0"] <> "") {
188
				if ((strpos($_POST["detail0"], "||") === false) && (substr($_POST["detail0"], 0, 1) != "|") && (substr($_POST["detail0"], -1, 1) != "|")) {
189
					$final_address_details[] = $_POST["detail0"];
190
				} 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
					$final_address_details[] = preg_replace('/\|\|+/', '|', trim($_POST["detail0"], "|"));
194
					$input_errors[] = $vertical_bar_err_text;
195
				}
196
			} else
197
				$final_address_details[] = sprintf(gettext("Entry added %s"), date('r'));
198
		}
199
	} else if ($_POST['type'] == "url" || $_POST['type'] == "url_ports") {
200
		$desc_fmt_err_found = false;
201

    
202
		/* item is a url type */
203
		for($x=0; $x<$max_alias_addresses-1; $x++) {
204
			$_POST['address' . $x] = trim($_POST['address' . $x]);
205
			if($_POST['address' . $x]) {
206
				/* fetch down and add in */
207
				$temp_filename = tempnam("{$g['tmp_path']}/", "alias_import");
208
				unlink_if_exists($temp_filename);
209
				$verify_ssl = isset($config['system']['checkaliasesurlcert']);
210
				mkdir($temp_filename);
211
				download_file($_POST['address' . $x], $temp_filename . "/aliases", $verify_ssl);
212

    
213
				/* if the item is tar gzipped then extract */
214
				if(stristr($_POST['address' . $x], ".tgz"))
215
					process_alias_tgz($temp_filename);
216
				else if(stristr($_POST['address' . $x], ".zip"))
217
					process_alias_unzip($temp_filename);
218

    
219
				if (!isset($alias['aliasurl']))
220
					$alias['aliasurl'] = array();
221

    
222
				$alias['aliasurl'][] = $_POST['address' . $x];
223
				if ($_POST["detail{$x}"] <> "") {
224
					if ((strpos($_POST["detail{$x}"], "||") === false) && (substr($_POST["detail{$x}"], 0, 1) != "|") && (substr($_POST["detail{$x}"], -1, 1) != "|")) {
225
						$final_address_details[] = $_POST["detail{$x}"];
226
					} else {
227
						/* Remove leading and trailing vertical bars and replace multiple vertical bars with single, */
228
						/* and put in the output array so the text is at least redisplayed for the user. */
229
						$final_address_details[] = preg_replace('/\|\|+/', '|', trim($_POST["detail{$x}"], "|"));
230
						if (!$desc_fmt_err_found) {
231
							$input_errors[] = $vertical_bar_err_text;
232
							$desc_fmt_err_found = true;
233
						}
234
					}
235
				} else
236
					$final_address_details[] = sprintf(gettext("Entry added %s"), date('r'));
237

    
238
				if(file_exists("{$temp_filename}/aliases")) {
239
					$address = parse_aliases_file("{$temp_filename}/aliases", $_POST['type'], 3000);
240
					if($address == null) {
241
						/* nothing was found */
242
						$input_errors[] = sprintf(gettext("You must provide a valid URL. Could not fetch usable data from '%s'."), $_POST['address' . $x]);
243
					}
244
					mwexec("/bin/rm -rf " . escapeshellarg($temp_filename));
245
				} else {
246
					$input_errors[] = sprintf(gettext("URL '%s' is not valid."), $_POST['address' . $x]);
247
				}
248
			}
249
		}
250
		unset($desc_fmt_err_found);
251
		if ($_POST['type'] == "url_ports")
252
			$address = group_ports($address);
253
	} else {
254
		/* item is a normal alias type */
255
		$wrongaliases = "";
256
		$desc_fmt_err_found = false;
257
		$alias_address_count = 0;
258

    
259
		// First trim and expand the input data. 
260
		// Users can paste strings like "10.1.2.0/24 10.3.0.0/16 9.10.11.0/24" into an address box.
261
		// They can also put an IP range.
262
		// This loop expands out that stuff so it can easily be validated.
263
		for($x=0; $x<($max_alias_addresses-1); $x++) {
264
			if($_POST["address{$x}"] <> "") {
265
				if ($_POST["detail{$x}"] <> "") {
266
					if ((strpos($_POST["detail{$x}"], "||") === false) && (substr($_POST["detail{$x}"], 0, 1) != "|") && (substr($_POST["detail{$x}"], -1, 1) != "|")) {
267
						$detail_text = $_POST["detail{$x}"];
268
					} else {
269
						/* Remove leading and trailing vertical bars and replace multiple vertical bars with single, */
270
						/* and put in the output array so the text is at least redisplayed for the user. */
271
						$detail_text = preg_replace('/\|\|+/', '|', trim($_POST["detail{$x}"], "|"));
272
						if (!$desc_fmt_err_found) {
273
							$input_errors[] = $vertical_bar_err_text;
274
							$desc_fmt_err_found = true;
275
						}
276
					}
277
				} else {
278
					$detail_text = sprintf(gettext("Entry added %s"), date('r'));
279
				}
280
				$address_items = explode(" ", trim($_POST["address{$x}"]));
281
				foreach ($address_items as $address_item) {
282
					$iprange_type = is_iprange($address_item);
283
					if ($iprange_type == 4) {
284
						list($startip, $endip) = explode('-', $address_item);
285
						if ($_POST['type'] == "network") {
286
							// For network type aliases, expand an IPv4 range into an array of subnets.
287
							$rangesubnets = ip_range_to_subnet_array($startip, $endip);
288
							foreach ($rangesubnets as $rangesubnet) {
289
								if ($alias_address_count > $max_alias_addresses) {
290
									break;
291
								}
292
								list($address_part, $subnet_part) = explode("/", $rangesubnet);
293
								$input_addresses[] = $address_part;
294
								$input_address_subnet[] = $subnet_part;
295
								$final_address_details[] = $detail_text;
296
								$alias_address_count++;
297
							}
298
						} else {
299
							// For host type aliases, expand an IPv4 range into a list of individual IPv4 addresses.
300
							$rangeaddresses = ip_range_to_address_array($startip, $endip, $max_alias_addresses - $alias_address_count);
301
							if (is_array($rangeaddresses)) {
302
								foreach ($rangeaddresses as $rangeaddress) {
303
									$input_addresses[] = $rangeaddress;
304
									$input_address_subnet[] = "";
305
									$final_address_details[] = $detail_text;
306
									$alias_address_count++;
307
								}
308
							} else {
309
								$input_errors[] = sprintf(gettext('Range is too large to expand into individual host IP addresses (%s)'), $address_item);
310
								$input_errors[] = sprintf(gettext('The maximum number of entries in an alias is %s'), $max_alias_addresses);
311
								// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
312
								$input_addresses[] = $address_item;
313
								$input_address_subnet[] = "";
314
								$final_address_details[] = $detail_text;
315
							}
316
						}
317
					} else if ($iprange_type == 6) {
318
						$input_errors[] = sprintf(gettext('IPv6 address ranges are not supported (%s)'), $address_item);
319
						// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
320
						$input_addresses[] = $address_item;
321
						$input_address_subnet[] = "";
322
						$final_address_details[] = $detail_text;
323
					} else {
324
						$subnet_type = is_subnet($address_item);
325
						if (($_POST['type'] == "host") && $subnet_type) {
326
							if ($subnet_type == 4) {
327
								// For host type aliases, if the user enters an IPv4 subnet, expand it into a list of individual IPv4 addresses.
328
								if (subnet_size($address_item) <= ($max_alias_addresses - $alias_address_count)) {
329
									$rangeaddresses = subnetv4_expand($address_item);
330
									foreach ($rangeaddresses as $rangeaddress) {
331
										$input_addresses[] = $rangeaddress;
332
										$input_address_subnet[] = "";
333
										$final_address_details[] = $detail_text;
334
										$alias_address_count++;
335
									}
336
								} else {
337
									$input_errors[] = sprintf(gettext('Subnet is too large to expand into individual host IP addresses (%s)'), $address_item);
338
									$input_errors[] = sprintf(gettext('The maximum number of entries in an alias is %s'), $max_alias_addresses);
339
									// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
340
									$input_addresses[] = $address_item;
341
									$input_address_subnet[] = "";
342
									$final_address_details[] = $detail_text;
343
								}
344
							} else {
345
								$input_errors[] = sprintf(gettext('IPv6 subnets are not supported in host aliases (%s)'), $address_item);
346
								// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
347
								$input_addresses[] = $address_item;
348
								$input_address_subnet[] = "";
349
								$final_address_details[] = $detail_text;
350
							}
351
						} else {
352
							list($address_part, $subnet_part) = explode("/", $address_item);
353
							if (!empty($subnet_part)) {
354
								if (is_subnet($address_item)) {
355
									$input_addresses[] = $address_part;
356
									$input_address_subnet[] = $subnet_part;
357
								} else {
358
									// The user typed something like "1.2.3.444/24" or "1.2.3.0/36" or similar rubbish.
359
									// Feed it through without splitting it apart, then it will be caught by the validation loop below.
360
									$input_addresses[] = $address_item;
361
									$input_address_subnet[] = "";
362
								}
363
							} else {
364
								$input_addresses[] = $address_part;
365
								$input_address_subnet[] = $_POST["address_subnet{$x}"];
366
							}
367
							$final_address_details[] = $detail_text;
368
							$alias_address_count++;
369
						}
370
					}
371
					if ($alias_address_count > $max_alias_addresses) {
372
						$input_errors[] = sprintf(gettext('The maximum number of entries in an alias has been exceeded (%s)'), $max_alias_addresses);
373
						break;
374
					}
375
				}
376
			}
377
		}
378

    
379
		// Validate the input data expanded above.
380
		foreach($input_addresses as $idx => $input_address) {
381
			if (is_alias($input_address)) {
382
				if (!alias_same_type($input_address, $_POST['type']))
383
					// But alias type network can include alias type urltable. Feature#1603.
384
					if (!($_POST['type'] == 'network' &&
385
						  preg_match("/urltable/i", alias_get_type($input_address))))
386
						$wrongaliases .= " " . $input_address;
387
			} else if ($_POST['type'] == "port") {
388
				if (!is_port($input_address) && !is_portrange($input_address))
389
					$input_errors[] = $input_address . " " . gettext("is not a valid port or alias.");
390
			} else if ($_POST['type'] == "host" || $_POST['type'] == "network") {
391
				if (is_subnet($input_address) || 
392
					(!is_ipaddr($input_address) && !is_hostname($input_address)))
393
					$input_errors[] = sprintf(gettext('%1$s is not a valid %2$s address, FQDN or alias.'), $input_address, $_POST['type']);
394
			}
395
			$tmpaddress = $input_address;
396
			if ($_POST['type'] != "host" && is_ipaddr($input_address) && $input_address_subnet[$idx] <> "") {
397
				if (!is_subnet($input_address . "/" . $input_address_subnet[$idx]))
398
					$input_errors[] = sprintf(gettext('%s/%s is not a valid subnet.'), $input_address, $input_address_subnet[$idx]);
399
				else
400
					$tmpaddress .= "/" . $input_address_subnet[$idx];
401
			}
402
			$address[] = $tmpaddress;
403
		}
404
		unset($desc_fmt_err_found);
405
		if ($wrongaliases <> "")
406
			$input_errors[] = sprintf(gettext('The alias(es): %s cannot be nested because they are not of the same type.'), $wrongaliases);
407
	}
408

    
409
	unset($vertical_bar_err_text);
410

    
411
	// Allow extending of the firewall edit page and include custom input validation
412
	pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/input_validation");
413

    
414
	if (!$input_errors) {
415
		$alias['address'] = is_array($address) ? implode(" ", $address) : $address;
416
		$alias['descr'] = $_POST['descr'];
417
		$alias['type'] = $_POST['type'];
418
		$alias['detail'] = implode("||", $final_address_details);
419

    
420
		/*   Check to see if alias name needs to be
421
		 *   renamed on referenced rules and such
422
		 */
423
		if ($_POST['name'] <> $_POST['origname']) {
424
			// Firewall rules
425
			update_alias_names_upon_change(array('filter', 'rule'), array('source', 'address'), $_POST['name'], $origname);
426
			update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
427
			update_alias_names_upon_change(array('filter', 'rule'), array('source', 'port'), $_POST['name'], $origname);
428
			update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'port'), $_POST['name'], $origname);
429
			// NAT Rules
430
			update_alias_names_upon_change(array('nat', 'rule'), array('source', 'address'), $_POST['name'], $origname);
431
			update_alias_names_upon_change(array('nat', 'rule'), array('source', 'port'), $_POST['name'], $origname);
432
			update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
433
			update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'port'), $_POST['name'], $origname);
434
			update_alias_names_upon_change(array('nat', 'rule'), array('target'), $_POST['name'], $origname);
435
			update_alias_names_upon_change(array('nat', 'rule'), array('local-port'), $_POST['name'], $origname);
436
			// NAT 1:1 Rules
437
			//update_alias_names_upon_change(array('nat', 'onetoone'), array('external'), $_POST['name'], $origname);
438
			//update_alias_names_upon_change(array('nat', 'onetoone'), array('source', 'address'), $_POST['name'], $origname);
439
			update_alias_names_upon_change(array('nat', 'onetoone'), array('destination', 'address'), $_POST['name'], $origname);
440
			// NAT Outbound Rules
441
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('source', 'network'), $_POST['name'], $origname);
442
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('sourceport'), $_POST['name'], $origname);
443
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
444
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('dstport'), $_POST['name'], $origname);
445
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('target'), $_POST['name'], $origname);
446
			// Alias in an alias
447
			update_alias_names_upon_change(array('aliases', 'alias'), array('address'), $_POST['name'], $origname);
448
		}
449

    
450
		pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/pre_write_config");
451

    
452
		if (isset($id) && $a_aliases[$id]) {
453
			if ($a_aliases[$id]['name'] <> $alias['name']) {
454
				foreach ($a_aliases as $aliasid => $aliasd) {
455
					if ($aliasd['address'] <> "") {
456
						$tmpdirty = false;
457
						$tmpaddr = explode(" ", $aliasd['address']);
458
						foreach ($tmpaddr as $tmpidx => $tmpalias) {
459
							if ($tmpalias == $a_aliases[$id]['name']) {
460
								$tmpaddr[$tmpidx] = $alias['name'];
461
								$tmpdirty = true;
462
							}
463
						}
464
						if ($tmpdirty == true)
465
							$a_aliases[$aliasid]['address'] = implode(" ", $tmpaddr);
466
					}
467
				}
468
			}
469
			$a_aliases[$id] = $alias;
470
		} else
471
			$a_aliases[] = $alias;
472

    
473
		// Sort list
474
		$a_aliases = msort($a_aliases, "name");
475

    
476
		if (write_config())
477
			mark_subsystem_dirty('aliases');
478

    
479
		if(!empty($tab))
480
			header("Location: firewall_aliases.php?tab=" . htmlspecialchars ($tab));
481
		else
482
			header("Location: firewall_aliases.php");
483
		exit;
484
	}
485
	//we received input errors, copy data to prevent retype
486
	else
487
	{
488
		$pconfig['name'] = $_POST['name'];
489
		$pconfig['descr'] = $_POST['descr'];
490
		if (($_POST['type'] == 'url') || ($_POST['type'] == 'url_ports'))
491
			$pconfig['address'] = implode(" ", $alias['aliasurl']);
492
		else
493
			$pconfig['address'] = implode(" ", $address);
494
		$pconfig['type'] = $_POST['type'];
495
		$pconfig['detail'] = implode("||", $final_address_details);
496
	}
497
}
498

    
499
include("head.inc");
500

    
501
$jscriptstr = <<<EOD
502

    
503
<script type="text/javascript">
504
//<![CDATA[
505
var objAlias = new Array(4999);
506
function typesel_change() {
507
	var field_disabled = 0;
508
	var field_value = "";
509
	var set_value = false;
510
	switch (document.iform.type.selectedIndex) {
511
		case 0:	/* host */
512
			field_disabled = 1;
513
			field_value = "";
514
			set_value = true;
515
			break;
516
		case 1:	/* network */
517
			field_disabled = 0;
518
			break;
519
		case 2:	/* port */
520
			field_disabled = 1;
521
			field_value = "128";
522
			set_value = true;
523
			break;
524
		case 3:	/* url */
525
			field_disabled = 1;
526
			break;
527
		case 4:	/* url_ports */
528
			field_disabled = 1;
529
			break;
530
		case 5:	/* urltable */
531
			field_disabled = 0;
532
			break;
533
		case 6:	/* urltable_ports */
534
			field_disabled = 0;
535
			break;
536
	}
537

    
538
	jQuery("select[id^='address_subnet']").prop("disabled", field_disabled);
539
	if (set_value == true)
540
		jQuery("select[id^='address_subnet']").prop("value", field_value);
541
}
542

    
543
function add_alias_control() {
544
	var name = "address" + (totalrows - 1);
545
	obj = document.getElementById(name);
546
	obj.setAttribute('class', 'formfldalias');
547
	obj.setAttribute('autocomplete', 'off');
548
	objAlias[totalrows - 1] = new AutoSuggestControl(obj, new StateSuggestions(addressarray));
549
}
550
EOD;
551

    
552
$network_str = gettext("Network or FQDN");
553
$networks_str = gettext("Network(s)");
554
$cidr_str = gettext("CIDR");
555
$description_str = gettext("Description");
556
$hosts_str = gettext("Host(s)");
557
$ip_str = gettext("IP or FQDN");
558
$ports_str = gettext("Port(s)");
559
$port_str = gettext("Port");
560
$url_str = gettext("URL (IPs)");
561
$url_ports_str = gettext("URL (Ports)");
562
$urltable_str = gettext("URL Table (IPs)");
563
$urltable_ports_str = gettext("URL Table (Ports)");
564
$update_freq_str = gettext("Update Freq. (days)");
565

    
566
$networks_help = gettext("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.");
567
$hosts_help = gettext("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.");
568
$ports_help = gettext("Enter as many ports as you wish.  Port ranges can be expressed by separating with a colon.");
569
$url_help = sprintf(gettext("Enter as many URLs as you wish. After saving %s will download the URL and import the items into the alias. Use only with small sets of IP addresses (less than 3000)."), $g['product_name']);
570
$url_ports_help = sprintf(gettext("Enter as many URLs as you wish. After saving %s will download the URL and import the items into the alias. Use only with small sets of Ports (less than 3000)."), $g['product_name']);
571
$urltable_help = sprintf(gettext("Enter a single URL containing a large number of IPs and/or Subnets. After saving %s 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."), $g['product_name']);
572
$urltable_ports_help = sprintf(gettext("Enter a single URL containing a list of Port numbers and/or Port ranges. After saving %s will download the URL."), $g['product_name']);
573

    
574
$openvpn_str = gettext("Username");
575
$openvpn_user_str = gettext("OpenVPN Users");
576
$openvpn_help = gettext("Enter as many usernames as you wish.");
577
$openvpn_freq = "";
578

    
579
$jscriptstr .= <<<EOD
580

    
581
function update_box_type() {
582
	var indexNum = document.forms[0].type.selectedIndex;
583
	var selected = document.forms[0].type.options[indexNum].text;
584
	if(selected == '{$networks_str}') {
585
		document.getElementById ("addressnetworkport").firstChild.data = "{$networks_str}";
586
		document.getElementById ("onecolumn").firstChild.data = "{$network_str}";
587
		document.getElementById ("twocolumn").firstChild.data = "{$cidr_str}";
588
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
589
		document.getElementById ("threecolumn").style.display = 'block';
590
		document.getElementById ("itemhelp").firstChild.data = "{$networks_help}";
591
		document.getElementById ("addrowbutton").style.display = 'block';
592
	} else if(selected == '{$hosts_str}') {
593
		document.getElementById ("addressnetworkport").firstChild.data = "{$hosts_str}";
594
		document.getElementById ("onecolumn").firstChild.data = "{$ip_str}";
595
		document.getElementById ("twocolumn").firstChild.data = "";
596
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
597
		document.getElementById ("threecolumn").style.display = 'block';
598
		document.getElementById ("itemhelp").firstChild.data = "{$hosts_help}";
599
		document.getElementById ("addrowbutton").style.display = 'block';
600
	} else if(selected == '{$ports_str}') {
601
		document.getElementById ("addressnetworkport").firstChild.data = "{$ports_str}";
602
		document.getElementById ("onecolumn").firstChild.data = "{$port_str}";
603
		document.getElementById ("twocolumn").firstChild.data = "";
604
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
605
		document.getElementById ("threecolumn").style.display = 'block';
606
		document.getElementById ("itemhelp").firstChild.data = "{$ports_help}";
607
		document.getElementById ("addrowbutton").style.display = 'block';
608
	} else if(selected == '{$url_str}') {
609
		document.getElementById ("addressnetworkport").firstChild.data = "{$url_str}";
610
		document.getElementById ("onecolumn").firstChild.data = "{$url_str}";
611
		document.getElementById ("twocolumn").firstChild.data = "";
612
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
613
		document.getElementById ("threecolumn").style.display = 'block';
614
		document.getElementById ("itemhelp").firstChild.data = "{$url_help}";
615
		document.getElementById ("addrowbutton").style.display = 'block';
616
	} else if(selected == '{$url_ports_str}') {
617
		document.getElementById ("addressnetworkport").firstChild.data = "{$url_ports_str}";
618
		document.getElementById ("onecolumn").firstChild.data = "{$url_ports_str}";
619
		document.getElementById ("twocolumn").firstChild.data = "";
620
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
621
		document.getElementById ("threecolumn").style.display = 'block';
622
		document.getElementById ("itemhelp").firstChild.data = "{$url_ports_help}";
623
		document.getElementById ("addrowbutton").style.display = 'block';
624
	} else if(selected == '{$openvpn_user_str}') {
625
		document.getElementById ("addressnetworkport").firstChild.data = "{$openvpn_user_str}";
626
		document.getElementById ("onecolumn").firstChild.data = "{$openvpn_str}";
627
		document.getElementById ("twocolumn").firstChild.data = "{$openvpn_freq}";
628
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
629
		document.getElementById ("threecolumn").style.display = 'block';
630
		document.getElementById ("itemhelp").firstChild.data = "{$openvpn_help}";
631
		document.getElementById ("addrowbutton").style.display = 'block';
632
	} else if(selected == '{$urltable_str}') {
633
		if ((typeof(totalrows) == "undefined") || (totalrows < 1)) {
634
			addRowTo('maintable', 'formfldalias');
635
			typesel_change();
636
			add_alias_control(this);
637
		}
638
		document.getElementById ("addressnetworkport").firstChild.data = "{$url_str}";
639
		document.getElementById ("onecolumn").firstChild.data = "{$url_str}";
640
		document.getElementById ("twocolumn").firstChild.data = "{$update_freq_str}";
641
		document.getElementById ("threecolumn").firstChild.data = "";
642
		document.getElementById ("threecolumn").style.display = 'none';
643
		document.getElementById ("itemhelp").firstChild.data = "{$urltable_help}";
644
		document.getElementById ("addrowbutton").style.display = 'none';
645
	} else if(selected == '{$urltable_ports_str}') {
646
		if ((typeof(totalrows) == "undefined") || (totalrows < 1)) {
647
			addRowTo('maintable', 'formfldalias');
648
			typesel_change();
649
			add_alias_control(this);
650
		}
651
		document.getElementById ("addressnetworkport").firstChild.data = "{$url_str}";
652
		document.getElementById ("onecolumn").firstChild.data = "{$url_str}";
653
		document.getElementById ("twocolumn").firstChild.data = "{$update_freq_str}";
654
		document.getElementById ("threecolumn").firstChild.data = "";
655
		document.getElementById ("threecolumn").style.display = 'none';
656
		document.getElementById ("itemhelp").firstChild.data = "{$urltable_ports_help}";
657
		document.getElementById ("addrowbutton").style.display = 'none';
658
	}
659
}
660
//]]>
661
</script>
662

    
663
EOD;
664

    
665
?>
666

    
667
<body link="#0000CC" vlink="#0000CC" alink="#0000CC" onload="<?= $jsevents["body"]["onload"] ?>">
668
<?php
669
	include("fbegin.inc");
670
	echo $jscriptstr;
671
?>
672

    
673
<script type="text/javascript" src="/javascript/jquery.ipv4v6ify.js"></script>
674
<script type="text/javascript" src="/javascript/row_helper.js"></script>
675
<script type="text/javascript" src="/javascript/autosuggest.js?rev=1"></script>
676
<script type="text/javascript" src="/javascript/suggestions.js"></script>
677

    
678
<input type='hidden' name='address_type' value='textbox' />
679
<input type='hidden' name='address_subnet_type' value='select' />
680

    
681
<script type="text/javascript">
682
//<![CDATA[
683
	rowname[0] = "address";
684
	rowtype[0] = "textbox,ipv4v6";
685
	rowsize[0] = "30";
686

    
687
	rowname[1] = "address_subnet";
688
	rowtype[1] = "select,ipv4v6";
689
	rowsize[1] = "1";
690

    
691
	rowname[2] = "detail";
692
	rowtype[2] = "textbox";
693
	rowsize[2] = "50";
694
//]]>
695
</script>
696

    
697
<?php pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/pre_input_errors"); ?>
698
<?php if ($input_errors) print_input_errors($input_errors); ?>
699
<div id="inputerrors"></div>
700

    
701
<form action="firewall_aliases_edit.php" method="post" name="iform" id="iform">
702
<?php
703
if (empty($tab)) {
704
	if (preg_match("/url/i", $pconfig['type']))
705
		$tab = 'url';
706
	else if ($pconfig['type'] == 'host')
707
		$tab = 'ip';
708
	else
709
		$tab = $pconfig['type'];
710
}
711
?>
712
<input name="tab" type="hidden" id="tab" value="<?=htmlspecialchars($tab);?>" />
713
<table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0" summary="firewall aliases edit">
714
	<tr>
715
		<td colspan="2" valign="top" class="listtopic"><?=gettext("Alias Edit"); ?></td>
716
	</tr>
717
	<tr>
718
		<td valign="top" class="vncellreq"><?=gettext("Name"); ?></td>
719
		<td class="vtable">
720
			<input name="origname" type="hidden" id="origname" class="formfld unknown" size="40" value="<?=htmlspecialchars($pconfig['name']);?>" />
721
			<input name="name" type="text" id="name" class="formfld unknown" size="40" maxlength="31" value="<?=htmlspecialchars($pconfig['name']);?>" />
722
			<?php if (isset($id) && $a_aliases[$id]): ?>
723
				<input name="id" type="hidden" value="<?=htmlspecialchars($id);?>" />
724
			<?php endif; ?>
725
			<br />
726
			<span class="vexpl">
727
				<?=gettext("The name of the alias may only consist of the characters \"a-z, A-Z, 0-9 and _\"."); ?>
728
			</span>
729
		</td>
730
	</tr>
731
	<?php pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/after_first_tr"); ?>
732
	<tr>
733
		<td width="22%" valign="top" class="vncell"><?=gettext("Description"); ?></td>
734
		<td width="78%" class="vtable">
735
			<input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>" />
736
			<br />
737
			<span class="vexpl">
738
				<?=gettext("You may enter a description here for your reference (not parsed)."); ?>
739
			</span>
740
		</td>
741
	</tr>
742
	<tr>
743
		<td valign="top" class="vncellreq"><?=gettext("Type"); ?></td>
744
		<td class="vtable">
745
			<select name="type" class="formselect" id="type" onchange="update_box_type(); typesel_change();">
746
				<option value="host" <?php if ($pconfig['type'] == "host") echo "selected=\"selected\""; ?>><?=gettext("Host(s)"); ?></option>
747
				<option value="network" <?php if ($pconfig['type'] == "network") echo "selected=\"selected\""; ?>><?=gettext("Network(s)"); ?></option>
748
				<option value="port" <?php if (($pconfig['type'] == "port") || (empty($pconfig['type']) && ($tab == "port"))) echo "selected=\"selected\""; ?>><?=gettext("Port(s)"); ?></option>
749
				<!--<option value="openvpn" <?php if ($pconfig['type'] == "openvpn") echo "selected=\"selected\""; ?>><?=gettext("OpenVPN Users"); ?></option> -->
750
				<option value="url" <?php if (($pconfig['type'] == "url") || (empty($pconfig['type']) && ($tab == "url"))) echo "selected=\"selected\""; ?>><?=gettext("URL (IPs)");?></option>
751
				<option value="url_ports" <?php if ($pconfig['type'] == "url_ports") echo "selected=\"selected\""; ?>><?=gettext("URL (Ports)");?></option>
752
				<option value="urltable" <?php if ($pconfig['type'] == "urltable") echo "selected=\"selected\""; ?>><?=gettext("URL Table (IPs)"); ?></option>
753
				<option value="urltable_ports" <?php if ($pconfig['type'] == "urltable_ports") echo "selected=\"selected\""; ?>><?=gettext("URL Table (Ports)"); ?></option>
754
			</select>
755
		</td>
756
	</tr>
757
	<tr>
758
		<td width="22%" valign="top" class="vncellreq"><div id="addressnetworkport"><?=gettext("Host(s)"); ?></div></td>
759
		<td width="78%" class="vtable">
760
			<table id="maintable" summary="maintable">
761
				<tbody>
762
					<tr>
763
						<td colspan="4">
764
							<div style="padding:5px; margin-top: 16px; margin-bottom: 16px; border:1px dashed #000066; background-color: #ffffff; color: #000000; font-size: 8pt;" id="itemhelp"><?=gettext("Item information"); ?></div>
765
						</td>
766
					</tr>
767
					<tr>
768
						<td><div id="onecolumn"><?=gettext("Network"); ?></div></td>
769
						<td><div id="twocolumn">CIDR</div></td>
770
						<td><div id="threecolumn"><?=gettext("Description"); ?></div></td>
771
					</tr>
772

    
773
					<?php
774
					$counter = 0;
775
					if ($pconfig['address'] <> ""):
776
						$addresses = explode(" ", $pconfig['address']);
777
						$details = explode("||", $pconfig['detail']);
778
						while ($counter < count($addresses)):
779
							if (($pconfig['type'] != "host") && is_subnet($addresses[$counter])) {
780
								list($address, $address_subnet) = explode("/", $addresses[$counter]);
781
							} else {
782
								$address = $addresses[$counter];
783
								$address_subnet = "";
784
							}
785
					?>
786
					<tr>
787
						<td>
788
							<input autocomplete="off" name="address<?php echo $counter; ?>" type="text" class="formfldalias ipv4v6" id="address<?php echo $counter; ?>" size="30" value="<?=htmlspecialchars($address);?>" />
789
						</td>
790
						<td>
791
							<select name="address_subnet<?php echo $counter; ?>" class="formselect ipv4v6" id="address_subnet<?php echo $counter; ?>">
792
								<option></option>
793
								<?php for ($i = 128; $i >= 1; $i--): ?>
794
									<option value="<?=$i;?>" <?php if (($i == $address_subnet) || ($i == $pconfig['updatefreq'])) echo "selected=\"selected\""; ?>><?=$i;?></option>
795
								<?php endfor; ?>
796
							</select>
797
						</td>
798
						<td>
799
							<input name="detail<?php echo $counter; ?>" type="text" class="formfld unknown" id="detail<?php echo $counter; ?>" size="50" value="<?=htmlspecialchars($details[$counter]);?>" />
800
						</td>
801
						<td>
802
							<a onclick="removeRow(this); return false;" href="#"><img border="0" src="/themes/<?echo $g['theme'];?>/images/icons/icon_x.gif" alt="" title="<?=gettext("remove this entry"); ?>" /></a>
803
						</td>
804
					</tr>
805
					<?php
806
						$counter++;
807

    
808
						endwhile;
809
					endif;
810
					?>
811
				</tbody>
812
			</table>
813
			<div id="addrowbutton">
814
				<a onclick="javascript:addRowTo('maintable', 'formfldalias'); typesel_change(); add_alias_control(this); return false;" href="#">
815
					<img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="<?=gettext("add another entry"); ?>" />
816
				</a>
817
			</div>
818
		</td>
819
	</tr>
820
	<tr>
821
		<td width="22%" valign="top">&nbsp;</td>
822
		<td width="78%">
823
			<input id="submit" name="submit" type="submit" class="formbtn" value="<?=gettext("Save"); ?>" />
824
			<input type="button" class="formbtn" value="<?=gettext("Cancel");?>" onclick="window.location.href='<?=$referer;?>'" />
825
		</td>
826
	</tr>
827
</table>
828
</form>
829

    
830
<script type="text/javascript">
831
//<![CDATA[
832
	field_counter_js = 3;
833
	rows = 1;
834
	totalrows = <?php echo $counter; ?>;
835
	loaded = <?php echo $counter; ?>;
836
	typesel_change();
837
	update_box_type();
838

    
839
	var addressarray = <?= json_encode(array_exclude($pconfig['name'], get_alias_list($pconfig['type']))) ?>;
840

    
841
	function createAutoSuggest() {
842
		<?php
843
		for ($jv = 0; $jv < $counter; $jv++)
844
			echo "objAlias[{$jv}] = new AutoSuggestControl(document.getElementById(\"address{$jv}\"), new StateSuggestions(addressarray));\n";
845
		?>
846
	}
847

    
848
	setTimeout("createAutoSuggest();", 500);
849
//]]>
850
</script>
851

    
852
<?php include("fend.inc"); ?>
853
</body>
854
</html>
(61-61/256)