Project

General

Profile

Download (38 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-2014 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
		$isfirst = 0;
175

    
176
		/* item is a url table type */
177
		if ($_POST['address0']) {
178
			/* fetch down and add in */
179
			$_POST['address0'] = trim($_POST['address0']);
180
			$isfirst = 0;
181
			$address[] = $_POST['address0'];
182
			$alias['url'] = $_POST['address0'];
183
			$alias['updatefreq'] = $_POST['address_subnet0'] ? $_POST['address_subnet0'] : 7;
184
			if (!is_URL($alias['url']) || empty($alias['url'])) {
185
				$input_errors[] = gettext("You must provide a valid URL.");
186
			} elseif (! process_alias_urltable($alias['name'], $alias['url'], 0, true)) {
187
				$input_errors[] = gettext("Unable to fetch usable data.");
188
			}
189
			if ($_POST["detail0"] <> "") {
190
				if ((strpos($_POST["detail0"], "||") === false) && (substr($_POST["detail0"], 0, 1) != "|") && (substr($_POST["detail0"], -1, 1) != "|")) {
191
					$final_address_details[] = $_POST["detail0"];
192
				} else {
193
					/* Remove leading and trailing vertical bars and replace multiple vertical bars with single, */
194
					/* and put in the output array so the text is at least redisplayed for the user. */
195
					$final_address_details[] = preg_replace('/\|\|+/', '|', trim($_POST["detail0"], "|"));
196
					$input_errors[] = $vertical_bar_err_text;
197
				}
198
			} else
199
				$final_address_details[] = sprintf(gettext("Entry added %s"), date('r'));
200
		}
201
	} else if ($_POST['type'] == "url" || $_POST['type'] == "url_ports") {
202
		$isfirst = 0;
203
		$address_count = 2;
204
		$desc_fmt_err_found = false;
205

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

    
218
				/* if the item is tar gzipped then extract */
219
				if(stristr($_POST['address' . $x], ".tgz"))
220
					process_alias_tgz($temp_filename);
221
				else if(stristr($_POST['address' . $x], ".zip"))
222
					process_alias_unzip($temp_filename);
223

    
224
				if (!isset($alias['aliasurl']))
225
					$alias['aliasurl'] = array();
226

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

    
243
				if(file_exists("{$temp_filename}/aliases")) {
244
					$file_contents = file_get_contents("{$temp_filename}/aliases");
245
					$file_contents = str_replace("#", "\n#", $file_contents);
246
					$file_contents_split = explode("\n", $file_contents);
247
					foreach($file_contents_split as $fc) {
248
						// Stop at 3000 items, aliases larger than that tend to break both pf and the WebGUI.
249
						if ($address_count >= 3000)
250
							break;
251
						$tmp = trim($fc);
252
						if(stristr($fc, "#")) {
253
							$tmp_split = explode("#", $tmp);
254
							$tmp = trim($tmp_split[0]);
255
						}
256
						$tmp = trim($tmp);
257
						if ($_POST['type'] == "url")
258
							$is_valid = (is_ipaddr($tmp) || is_subnet($tmp));
259
						else
260
							$is_valid = (is_port($tmp) || is_portrange($tmp));
261

    
262
						if (!empty($tmp) && $is_valid) {
263
							$address[] = $tmp;
264
							$isfirst = 1;
265
							$address_count++;
266
						}
267
					}
268
					if($isfirst == 0) {
269
						/* nothing was found */
270
						$input_errors[] = sprintf(gettext("You must provide a valid URL. Could not fetch usable data from '%s'."), $_POST['address' . $x]);
271
					}
272
					mwexec("/bin/rm -rf " . escapeshellarg($temp_filename));
273
				} else {
274
					$input_errors[] = sprintf(gettext("URL '%s' is not valid."), $_POST['address' . $x]);
275
				}
276
			}
277
		}
278
		unset($desc_fmt_err_found);
279
		if ($_POST['type'] == "url_ports")
280
			$address = group_ports($address);
281
	} else {
282
		/* item is a normal alias type */
283
		$wrongaliases = "";
284
		$desc_fmt_err_found = false;
285
		$alias_address_count = 0;
286

    
287
		// First trim and expand the input data. 
288
		// Users can paste strings like "10.1.2.0/24 10.3.0.0/16 9.10.11.0/24" into an address box.
289
		// They can also put an IP range.
290
		// This loop expands out that stuff so it can easily be validated.
291
		for($x=0; $x<($max_alias_addresses-1); $x++) {
292
			if($_POST["address{$x}"] <> "") {
293
				if ($_POST["detail{$x}"] <> "") {
294
					if ((strpos($_POST["detail{$x}"], "||") === false) && (substr($_POST["detail{$x}"], 0, 1) != "|") && (substr($_POST["detail{$x}"], -1, 1) != "|")) {
295
						$detail_text = $_POST["detail{$x}"];
296
					} else {
297
						/* Remove leading and trailing vertical bars and replace multiple vertical bars with single, */
298
						/* and put in the output array so the text is at least redisplayed for the user. */
299
						$detail_text = preg_replace('/\|\|+/', '|', trim($_POST["detail{$x}"], "|"));
300
						if (!$desc_fmt_err_found) {
301
							$input_errors[] = $vertical_bar_err_text;
302
							$desc_fmt_err_found = true;
303
						}
304
					}
305
				} else {
306
					$detail_text = sprintf(gettext("Entry added %s"), date('r'));
307
				}
308
				$address_items = explode(" ", trim($_POST["address{$x}"]));
309
				foreach ($address_items as $address_item) {
310
					$iprange_type = is_iprange($address_item);
311
					if ($iprange_type == 4) {
312
						list($startip, $endip) = explode('-', $address_item);
313
						if ($_POST['type'] == "network") {
314
							// For network type aliases, expand an IPv4 range into an array of subnets.
315
							$rangesubnets = ip_range_to_subnet_array($startip, $endip);
316
							foreach ($rangesubnets as $rangesubnet) {
317
								if ($alias_address_count > $max_alias_addresses) {
318
									break;
319
								}
320
								list($address_part, $subnet_part) = explode("/", $rangesubnet);
321
								$input_addresses[] = $address_part;
322
								$input_address_subnet[] = $subnet_part;
323
								$final_address_details[] = $detail_text;
324
								$alias_address_count++;
325
							}
326
						} else {
327
							// For host type aliases, expand an IPv4 range into a list of individual IPv4 addresses.
328
							$rangeaddresses = ip_range_to_address_array($startip, $endip, $max_alias_addresses - $alias_address_count);
329
							if (is_array($rangeaddresses)) {
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('Range 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
						}
345
					} else if ($iprange_type == 6) {
346
						$input_errors[] = sprintf(gettext('IPv6 address ranges are not supported (%s)'), $address_item);
347
						// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
348
						$input_addresses[] = $address_item;
349
						$input_address_subnet[] = "";
350
						$final_address_details[] = $detail_text;
351
					} else {
352
						$subnet_type = is_subnet($address_item);
353
						if (($_POST['type'] == "host") && $subnet_type) {
354
							if ($subnet_type == 4) {
355
								// For host type aliases, if the user enters an IPv4 subnet, expand it into a list of individual IPv4 addresses.
356
								if (subnet_size($address_item) <= ($max_alias_addresses - $alias_address_count)) {
357
									$rangeaddresses = subnetv4_expand($address_item);
358
									foreach ($rangeaddresses as $rangeaddress) {
359
										$input_addresses[] = $rangeaddress;
360
										$input_address_subnet[] = "";
361
										$final_address_details[] = $detail_text;
362
										$alias_address_count++;
363
									}
364
								} else {
365
									$input_errors[] = sprintf(gettext('Subnet is too large to expand into individual host IP addresses (%s)'), $address_item);
366
									$input_errors[] = sprintf(gettext('The maximum number of entries in an alias is %s'), $max_alias_addresses);
367
									// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
368
									$input_addresses[] = $address_item;
369
									$input_address_subnet[] = "";
370
									$final_address_details[] = $detail_text;
371
								}
372
							} else {
373
								$input_errors[] = sprintf(gettext('IPv6 subnets are not supported in host aliases (%s)'), $address_item);
374
								// Put the user-entered data in the output anyway, so it will be re-displayed for correction.
375
								$input_addresses[] = $address_item;
376
								$input_address_subnet[] = "";
377
								$final_address_details[] = $detail_text;
378
							}
379
						} else {
380
							list($address_part, $subnet_part) = explode("/", $address_item);
381
							if (!empty($subnet_part)) {
382
								if (is_subnet($address_item)) {
383
									$input_addresses[] = $address_part;
384
									$input_address_subnet[] = $subnet_part;
385
								} else {
386
									// The user typed something like "1.2.3.444/24" or "1.2.3.0/36" or similar rubbish.
387
									// Feed it through without splitting it apart, then it will be caught by the validation loop below.
388
									$input_addresses[] = $address_item;
389
									$input_address_subnet[] = "";
390
								}
391
							} else {
392
								$input_addresses[] = $address_part;
393
								$input_address_subnet[] = $_POST["address_subnet{$x}"];
394
							}
395
							$final_address_details[] = $detail_text;
396
							$alias_address_count++;
397
						}
398
					}
399
					if ($alias_address_count > $max_alias_addresses) {
400
						$input_errors[] = sprintf(gettext('The maximum number of entries in an alias has been exceeded (%s)'), $max_alias_addresses);
401
						break;
402
					}
403
				}
404
			}
405
		}
406

    
407
		// Validate the input data expanded above.
408
		foreach($input_addresses as $idx => $input_address) {
409
			if (is_alias($input_address)) {
410
				if (!alias_same_type($input_address, $_POST['type']))
411
					// But alias type network can include alias type urltable. Feature#1603.
412
					if (!($_POST['type'] == 'network' &&
413
						  preg_match("/urltable/i", alias_get_type($input_address))))
414
						$wrongaliases .= " " . $input_address;
415
			} else if ($_POST['type'] == "port") {
416
				if (!is_port($input_address) && !is_portrange($input_address))
417
					$input_errors[] = $input_address . " " . gettext("is not a valid port or alias.");
418
			} else if ($_POST['type'] == "host" || $_POST['type'] == "network") {
419
				if (is_subnet($input_address) || 
420
					(!is_ipaddr($input_address) && !is_hostname($input_address)))
421
					$input_errors[] = sprintf(gettext('%1$s is not a valid %2$s address, FQDN or alias.'), $input_address, $_POST['type']);
422
			}
423
			$tmpaddress = $input_address;
424
			if ($_POST['type'] != "host" && is_ipaddr($input_address) && $input_address_subnet[$idx] <> "") {
425
				if (!is_subnet($input_address . "/" . $input_address_subnet[$idx]))
426
					$input_errors[] = sprintf(gettext('%s/%s is not a valid subnet.'), $input_address, $input_address_subnet[$idx]);
427
				else
428
					$tmpaddress .= "/" . $input_address_subnet[$idx];
429
			}
430
			$address[] = $tmpaddress;
431
		}
432
		unset($desc_fmt_err_found);
433
		if ($wrongaliases <> "")
434
			$input_errors[] = sprintf(gettext('The alias(es): %s cannot be nested because they are not of the same type.'), $wrongaliases);
435
	}
436

    
437
	unset($vertical_bar_err_text);
438

    
439
	// Allow extending of the firewall edit page and include custom input validation
440
	pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/input_validation");
441

    
442
	if (!$input_errors) {
443
		$alias['address'] = is_array($address) ? implode(" ", $address) : $address;
444
		$alias['descr'] = $_POST['descr'];
445
		$alias['type'] = $_POST['type'];
446
		$alias['detail'] = implode("||", $final_address_details);
447

    
448
		/*   Check to see if alias name needs to be
449
		 *   renamed on referenced rules and such
450
		 */
451
		if ($_POST['name'] <> $_POST['origname']) {
452
			// Firewall rules
453
			update_alias_names_upon_change(array('filter', 'rule'), array('source', 'address'), $_POST['name'], $origname);
454
			update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
455
			update_alias_names_upon_change(array('filter', 'rule'), array('source', 'port'), $_POST['name'], $origname);
456
			update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'port'), $_POST['name'], $origname);
457
			// NAT Rules
458
			update_alias_names_upon_change(array('nat', 'rule'), array('source', 'address'), $_POST['name'], $origname);
459
			update_alias_names_upon_change(array('nat', 'rule'), array('source', 'port'), $_POST['name'], $origname);
460
			update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
461
			update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'port'), $_POST['name'], $origname);
462
			update_alias_names_upon_change(array('nat', 'rule'), array('target'), $_POST['name'], $origname);
463
			update_alias_names_upon_change(array('nat', 'rule'), array('local-port'), $_POST['name'], $origname);
464
			// NAT 1:1 Rules
465
			//update_alias_names_upon_change(array('nat', 'onetoone'), array('external'), $_POST['name'], $origname);
466
			//update_alias_names_upon_change(array('nat', 'onetoone'), array('source', 'address'), $_POST['name'], $origname);
467
			update_alias_names_upon_change(array('nat', 'onetoone'), array('destination', 'address'), $_POST['name'], $origname);
468
			// NAT Outbound Rules
469
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('source', 'network'), $_POST['name'], $origname);
470
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('sourceport'), $_POST['name'], $origname);
471
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
472
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('dstport'), $_POST['name'], $origname);
473
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('target'), $_POST['name'], $origname);
474
			// Alias in an alias
475
			update_alias_names_upon_change(array('aliases', 'alias'), array('address'), $_POST['name'], $origname);
476
		}
477

    
478
		pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/pre_write_config");
479

    
480
		if (isset($id) && $a_aliases[$id]) {
481
			if ($a_aliases[$id]['name'] <> $alias['name']) {
482
				foreach ($a_aliases as $aliasid => $aliasd) {
483
					if ($aliasd['address'] <> "") {
484
						$tmpdirty = false;
485
						$tmpaddr = explode(" ", $aliasd['address']);
486
						foreach ($tmpaddr as $tmpidx => $tmpalias) {
487
							if ($tmpalias == $a_aliases[$id]['name']) {
488
								$tmpaddr[$tmpidx] = $alias['name'];
489
								$tmpdirty = true;
490
							}
491
						}
492
						if ($tmpdirty == true)
493
							$a_aliases[$aliasid]['address'] = implode(" ", $tmpaddr);
494
					}
495
				}
496
			}
497
			$a_aliases[$id] = $alias;
498
		} else
499
			$a_aliases[] = $alias;
500

    
501
		// Sort list
502
		$a_aliases = msort($a_aliases, "name");
503

    
504
		if (write_config())
505
			mark_subsystem_dirty('aliases');
506

    
507
		if(!empty($tab))
508
			header("Location: firewall_aliases.php?tab=" . htmlspecialchars ($tab));
509
		else
510
			header("Location: firewall_aliases.php");
511
		exit;
512
	}
513
	//we received input errors, copy data to prevent retype
514
	else
515
	{
516
		$pconfig['name'] = $_POST['name'];
517
		$pconfig['descr'] = $_POST['descr'];
518
		if (($_POST['type'] == 'url') || ($_POST['type'] == 'url_ports'))
519
			$pconfig['address'] = implode(" ", $alias['aliasurl']);
520
		else
521
			$pconfig['address'] = implode(" ", $address);
522
		$pconfig['type'] = $_POST['type'];
523
		$pconfig['detail'] = implode("||", $final_address_details);
524
	}
525
}
526

    
527
include("head.inc");
528

    
529
$jscriptstr = <<<EOD
530

    
531
<script type="text/javascript">
532
//<![CDATA[
533
var objAlias = new Array(4999);
534
function typesel_change() {
535
	var field_disabled = 0;
536
	var field_value = "";
537
	var set_value = false;
538
	switch (document.iform.type.selectedIndex) {
539
		case 0:	/* host */
540
			field_disabled = 1;
541
			field_value = "";
542
			set_value = true;
543
			break;
544
		case 1:	/* network */
545
			field_disabled = 0;
546
			break;
547
		case 2:	/* port */
548
			field_disabled = 1;
549
			field_value = "128";
550
			set_value = true;
551
			break;
552
		case 3:	/* url */
553
			field_disabled = 1;
554
			break;
555
		case 4:	/* url_ports */
556
			field_disabled = 1;
557
			break;
558
		case 5:	/* urltable */
559
			field_disabled = 0;
560
			break;
561
		case 6:	/* urltable_ports */
562
			field_disabled = 0;
563
			break;
564
	}
565

    
566
	jQuery("select[id^='address_subnet']").prop("disabled", field_disabled);
567
	if (set_value == true)
568
		jQuery("select[id^='address_subnet']").prop("value", field_value);
569
}
570

    
571
function add_alias_control() {
572
	var name = "address" + (totalrows - 1);
573
	obj = document.getElementById(name);
574
	obj.setAttribute('class', 'formfldalias');
575
	obj.setAttribute('autocomplete', 'off');
576
	objAlias[totalrows - 1] = new AutoSuggestControl(obj, new StateSuggestions(addressarray));
577
}
578
EOD;
579

    
580
$network_str = gettext("Network or FQDN");
581
$networks_str = gettext("Network(s)");
582
$cidr_str = gettext("CIDR");
583
$description_str = gettext("Description");
584
$hosts_str = gettext("Host(s)");
585
$ip_str = gettext("IP or FQDN");
586
$ports_str = gettext("Port(s)");
587
$port_str = gettext("Port");
588
$url_str = gettext("URL (IPs)");
589
$url_ports_str = gettext("URL (Ports)");
590
$urltable_str = gettext("URL Table (IPs)");
591
$urltable_ports_str = gettext("URL Table (Ports)");
592
$update_freq_str = gettext("Update Freq. (days)");
593

    
594
$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.");
595
$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.");
596
$ports_help = gettext("Enter as many ports as you wish.  Port ranges can be expressed by separating with a colon.");
597
$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']);
598
$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']);
599
$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']);
600
$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']);
601

    
602
$openvpn_str = gettext("Username");
603
$openvpn_user_str = gettext("OpenVPN Users");
604
$openvpn_help = gettext("Enter as many usernames as you wish.");
605
$openvpn_freq = "";
606

    
607
$jscriptstr .= <<<EOD
608

    
609
function update_box_type() {
610
	var indexNum = document.forms[0].type.selectedIndex;
611
	var selected = document.forms[0].type.options[indexNum].text;
612
	if(selected == '{$networks_str}') {
613
		document.getElementById ("addressnetworkport").firstChild.data = "{$networks_str}";
614
		document.getElementById ("onecolumn").firstChild.data = "{$network_str}";
615
		document.getElementById ("twocolumn").firstChild.data = "{$cidr_str}";
616
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
617
		document.getElementById ("threecolumn").style.display = 'block';
618
		document.getElementById ("itemhelp").firstChild.data = "{$networks_help}";
619
		document.getElementById ("addrowbutton").style.display = 'block';
620
	} else if(selected == '{$hosts_str}') {
621
		document.getElementById ("addressnetworkport").firstChild.data = "{$hosts_str}";
622
		document.getElementById ("onecolumn").firstChild.data = "{$ip_str}";
623
		document.getElementById ("twocolumn").firstChild.data = "";
624
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
625
		document.getElementById ("threecolumn").style.display = 'block';
626
		document.getElementById ("itemhelp").firstChild.data = "{$hosts_help}";
627
		document.getElementById ("addrowbutton").style.display = 'block';
628
	} else if(selected == '{$ports_str}') {
629
		document.getElementById ("addressnetworkport").firstChild.data = "{$ports_str}";
630
		document.getElementById ("onecolumn").firstChild.data = "{$port_str}";
631
		document.getElementById ("twocolumn").firstChild.data = "";
632
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
633
		document.getElementById ("threecolumn").style.display = 'block';
634
		document.getElementById ("itemhelp").firstChild.data = "{$ports_help}";
635
		document.getElementById ("addrowbutton").style.display = 'block';
636
	} else if(selected == '{$url_str}') {
637
		document.getElementById ("addressnetworkport").firstChild.data = "{$url_str}";
638
		document.getElementById ("onecolumn").firstChild.data = "{$url_str}";
639
		document.getElementById ("twocolumn").firstChild.data = "";
640
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
641
		document.getElementById ("threecolumn").style.display = 'block';
642
		document.getElementById ("itemhelp").firstChild.data = "{$url_help}";
643
		document.getElementById ("addrowbutton").style.display = 'block';
644
	} else if(selected == '{$url_ports_str}') {
645
		document.getElementById ("addressnetworkport").firstChild.data = "{$url_ports_str}";
646
		document.getElementById ("onecolumn").firstChild.data = "{$url_ports_str}";
647
		document.getElementById ("twocolumn").firstChild.data = "";
648
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
649
		document.getElementById ("threecolumn").style.display = 'block';
650
		document.getElementById ("itemhelp").firstChild.data = "{$url_ports_help}";
651
		document.getElementById ("addrowbutton").style.display = 'block';
652
	} else if(selected == '{$openvpn_user_str}') {
653
		document.getElementById ("addressnetworkport").firstChild.data = "{$openvpn_user_str}";
654
		document.getElementById ("onecolumn").firstChild.data = "{$openvpn_str}";
655
		document.getElementById ("twocolumn").firstChild.data = "{$openvpn_freq}";
656
		document.getElementById ("threecolumn").firstChild.data = "{$description_str}";
657
		document.getElementById ("threecolumn").style.display = 'block';
658
		document.getElementById ("itemhelp").firstChild.data = "{$openvpn_help}";
659
		document.getElementById ("addrowbutton").style.display = 'block';
660
	} else if(selected == '{$urltable_str}') {
661
		if ((typeof(totalrows) == "undefined") || (totalrows < 1)) {
662
			addRowTo('maintable', 'formfldalias');
663
			typesel_change();
664
			add_alias_control(this);
665
		}
666
		document.getElementById ("addressnetworkport").firstChild.data = "{$url_str}";
667
		document.getElementById ("onecolumn").firstChild.data = "{$url_str}";
668
		document.getElementById ("twocolumn").firstChild.data = "{$update_freq_str}";
669
		document.getElementById ("threecolumn").firstChild.data = "";
670
		document.getElementById ("threecolumn").style.display = 'none';
671
		document.getElementById ("itemhelp").firstChild.data = "{$urltable_help}";
672
		document.getElementById ("addrowbutton").style.display = 'none';
673
	} else if(selected == '{$urltable_ports_str}') {
674
		if ((typeof(totalrows) == "undefined") || (totalrows < 1)) {
675
			addRowTo('maintable', 'formfldalias');
676
			typesel_change();
677
			add_alias_control(this);
678
		}
679
		document.getElementById ("addressnetworkport").firstChild.data = "{$url_str}";
680
		document.getElementById ("onecolumn").firstChild.data = "{$url_str}";
681
		document.getElementById ("twocolumn").firstChild.data = "{$update_freq_str}";
682
		document.getElementById ("threecolumn").firstChild.data = "";
683
		document.getElementById ("threecolumn").style.display = 'none';
684
		document.getElementById ("itemhelp").firstChild.data = "{$urltable_ports_help}";
685
		document.getElementById ("addrowbutton").style.display = 'none';
686
	}
687
}
688
//]]>
689
</script>
690

    
691
EOD;
692

    
693
?>
694

    
695
<body link="#0000CC" vlink="#0000CC" alink="#0000CC" onload="<?= $jsevents["body"]["onload"] ?>">
696
<?php
697
	include("fbegin.inc");
698
	echo $jscriptstr;
699
?>
700

    
701
<script type="text/javascript" src="/javascript/jquery.ipv4v6ify.js"></script>
702
<script type="text/javascript" src="/javascript/row_helper.js"></script>
703
<script type="text/javascript" src="/javascript/autosuggest.js"></script>
704
<script type="text/javascript" src="/javascript/suggestions.js"></script>
705

    
706
<input type='hidden' name='address_type' value='textbox' />
707
<input type='hidden' name='address_subnet_type' value='select' />
708

    
709
<script type="text/javascript">
710
//<![CDATA[
711
	rowname[0] = "address";
712
	rowtype[0] = "textbox,ipv4v6";
713
	rowsize[0] = "30";
714

    
715
	rowname[1] = "address_subnet";
716
	rowtype[1] = "select,ipv4v6";
717
	rowsize[1] = "1";
718

    
719
	rowname[2] = "detail";
720
	rowtype[2] = "textbox";
721
	rowsize[2] = "50";
722
//]]>
723
</script>
724

    
725
<?php pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/pre_input_errors"); ?>
726
<?php if ($input_errors) print_input_errors($input_errors); ?>
727
<div id="inputerrors"></div>
728

    
729
<form action="firewall_aliases_edit.php" method="post" name="iform" id="iform">
730
<?php
731
if (empty($tab)) {
732
	if (preg_match("/url/i", $pconfig['type']))
733
		$tab = 'url';
734
	else if ($pconfig['type'] == 'host')
735
		$tab = 'ip';
736
	else
737
		$tab = $pconfig['type'];
738
}
739
?>
740
<input name="tab" type="hidden" id="tab" value="<?=htmlspecialchars($tab);?>" />
741
<table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0" summary="firewall aliases edit">
742
	<tr>
743
		<td colspan="2" valign="top" class="listtopic"><?=gettext("Alias Edit"); ?></td>
744
	</tr>
745
	<tr>
746
		<td valign="top" class="vncellreq"><?=gettext("Name"); ?></td>
747
		<td class="vtable">
748
			<input name="origname" type="hidden" id="origname" class="formfld unknown" size="40" value="<?=htmlspecialchars($pconfig['name']);?>" />
749
			<input name="name" type="text" id="name" class="formfld unknown" size="40" maxlength="31" value="<?=htmlspecialchars($pconfig['name']);?>" />
750
			<?php if (isset($id) && $a_aliases[$id]): ?>
751
				<input name="id" type="hidden" value="<?=htmlspecialchars($id);?>" />
752
			<?php endif; ?>
753
			<br />
754
			<span class="vexpl">
755
				<?=gettext("The name of the alias may only consist of the characters \"a-z, A-Z, 0-9 and _\"."); ?>
756
			</span>
757
		</td>
758
	</tr>
759
	<?php pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/after_first_tr"); ?>
760
	<tr>
761
		<td width="22%" valign="top" class="vncell"><?=gettext("Description"); ?></td>
762
		<td width="78%" class="vtable">
763
			<input name="descr" type="text" class="formfld unknown" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>" />
764
			<br />
765
			<span class="vexpl">
766
				<?=gettext("You may enter a description here for your reference (not parsed)."); ?>
767
			</span>
768
		</td>
769
	</tr>
770
	<tr>
771
		<td valign="top" class="vncellreq"><?=gettext("Type"); ?></td>
772
		<td class="vtable">
773
			<select name="type" class="formselect" id="type" onchange="update_box_type(); typesel_change();">
774
				<option value="host" <?php if ($pconfig['type'] == "host") echo "selected=\"selected\""; ?>><?=gettext("Host(s)"); ?></option>
775
				<option value="network" <?php if ($pconfig['type'] == "network") echo "selected=\"selected\""; ?>><?=gettext("Network(s)"); ?></option>
776
				<option value="port" <?php if (($pconfig['type'] == "port") || (empty($pconfig['type']) && ($tab == "port"))) echo "selected=\"selected\""; ?>><?=gettext("Port(s)"); ?></option>
777
				<!--<option value="openvpn" <?php if ($pconfig['type'] == "openvpn") echo "selected=\"selected\""; ?>><?=gettext("OpenVPN Users"); ?></option> -->
778
				<option value="url" <?php if (($pconfig['type'] == "url") || (empty($pconfig['type']) && ($tab == "url"))) echo "selected=\"selected\""; ?>><?=gettext("URL (IPs)");?></option>
779
				<option value="url_ports" <?php if ($pconfig['type'] == "url_ports") echo "selected=\"selected\""; ?>><?=gettext("URL (Ports)");?></option>
780
				<option value="urltable" <?php if ($pconfig['type'] == "urltable") echo "selected=\"selected\""; ?>><?=gettext("URL Table (IPs)"); ?></option>
781
				<option value="urltable_ports" <?php if ($pconfig['type'] == "urltable_ports") echo "selected=\"selected\""; ?>><?=gettext("URL Table (Ports)"); ?></option>
782
			</select>
783
		</td>
784
	</tr>
785
	<tr>
786
		<td width="22%" valign="top" class="vncellreq"><div id="addressnetworkport"><?=gettext("Host(s)"); ?></div></td>
787
		<td width="78%" class="vtable">
788
			<table id="maintable" summary="maintable">
789
				<tbody>
790
					<tr>
791
						<td colspan="4">
792
							<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>
793
						</td>
794
					</tr>
795
					<tr>
796
						<td><div id="onecolumn"><?=gettext("Network"); ?></div></td>
797
						<td><div id="twocolumn">CIDR</div></td>
798
						<td><div id="threecolumn"><?=gettext("Description"); ?></div></td>
799
					</tr>
800

    
801
					<?php
802
					$counter = 0;
803
					if ($pconfig['address'] <> ""):
804
						$addresses = explode(" ", $pconfig['address']);
805
						$details = explode("||", $pconfig['detail']);
806
						while ($counter < count($addresses)):
807
							if (($pconfig['type'] != "host") && is_subnet($addresses[$counter])) {
808
								list($address, $address_subnet) = explode("/", $addresses[$counter]);
809
							} else {
810
								$address = $addresses[$counter];
811
								$address_subnet = "";
812
							}
813
					?>
814
					<tr>
815
						<td>
816
							<input autocomplete="off" name="address<?php echo $counter; ?>" type="text" class="formfldalias ipv4v6" id="address<?php echo $counter; ?>" size="30" value="<?=htmlspecialchars($address);?>" />
817
						</td>
818
						<td>
819
							<select name="address_subnet<?php echo $counter; ?>" class="formselect ipv4v6" id="address_subnet<?php echo $counter; ?>">
820
								<option></option>
821
								<?php for ($i = 128; $i >= 1; $i--): ?>
822
									<option value="<?=$i;?>" <?php if (($i == $address_subnet) || ($i == $pconfig['updatefreq'])) echo "selected=\"selected\""; ?>><?=$i;?></option>
823
								<?php endfor; ?>
824
							</select>
825
						</td>
826
						<td>
827
							<input name="detail<?php echo $counter; ?>" type="text" class="formfld unknown" id="detail<?php echo $counter; ?>" size="50" value="<?=htmlspecialchars($details[$counter]);?>" />
828
						</td>
829
						<td>
830
							<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>
831
						</td>
832
					</tr>
833
					<?php
834
						$counter++;
835

    
836
						endwhile;
837
					endif;
838
					?>
839
				</tbody>
840
			</table>
841
			<div id="addrowbutton">
842
				<a onclick="javascript:addRowTo('maintable', 'formfldalias'); typesel_change(); add_alias_control(this); return false;" href="#">
843
					<img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="<?=gettext("add another entry"); ?>" />
844
				</a>
845
			</div>
846
		</td>
847
	</tr>
848
	<tr>
849
		<td width="22%" valign="top">&nbsp;</td>
850
		<td width="78%">
851
			<input id="submit" name="submit" type="submit" class="formbtn" value="<?=gettext("Save"); ?>" />
852
			<input type="button" class="formbtn" value="<?=gettext("Cancel");?>" onclick="window.location.href='<?=$referer;?>'" />
853
		</td>
854
	</tr>
855
</table>
856
</form>
857

    
858
<script type="text/javascript">
859
//<![CDATA[
860
	field_counter_js = 3;
861
	rows = 1;
862
	totalrows = <?php echo $counter; ?>;
863
	loaded = <?php echo $counter; ?>;
864
	typesel_change();
865
	update_box_type();
866

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

    
869
	function createAutoSuggest() {
870
		<?php
871
		for ($jv = 0; $jv < $counter; $jv++)
872
			echo "objAlias[{$jv}] = new AutoSuggestControl(document.getElementById(\"address{$jv}\"), new StateSuggestions(addressarray));\n";
873
		?>
874
	}
875

    
876
	setTimeout("createAutoSuggest();", 500);
877
//]]>
878
</script>
879

    
880
<?php include("fend.inc"); ?>
881
</body>
882
</html>
(61-61/256)