Project

General

Profile

Download (25.8 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['address'][0]) {
177
			/* fetch down and add in */
178
			$_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
			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["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
				} 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["detail"][0], "|"));
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
			foreach ($_POST['address'] as $idx => $post_address) {
204
				/* fetch down and add in */
205
				$temp_filename = tempnam("{$g['tmp_path']}/", "alias_import");
206
				unlink_if_exists($temp_filename);
207
				$verify_ssl = isset($config['system']['checkaliasesurlcert']);
208
				mkdir($temp_filename);
209
				download_file($post_address, $temp_filename . "/aliases", $verify_ssl);
210

    
211
				/* if the item is tar gzipped then extract */
212
				if(stristr($post_address, ".tgz"))
213
					process_alias_tgz($temp_filename);
214
				else if(stristr($post_address, ".zip"))
215
					process_alias_unzip($temp_filename);
216

    
217
				if (!isset($alias['aliasurl']))
218
					$alias['aliasurl'] = array();
219

    
220
				$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
					} 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
						$final_address_details[] = preg_replace('/\|\|+/', '|', trim($_POST['detail'][$idx], "|"));
228
						if (!$desc_fmt_err_found) {
229
							$input_errors[] = $vertical_bar_err_text;
230
							$desc_fmt_err_found = true;
231
						}
232
					}
233
				} else
234
					$final_address_details[] = sprintf(gettext("Entry added %s"), date('r'));
235

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

    
256
		// First trim and expand the input data.
257
		// 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
			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
					} 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
						$detail_text = preg_replace('/\|\|+/', '|', trim($post_address, "|"));
268
						if (!$desc_fmt_err_found) {
269
							$input_errors[] = $vertical_bar_err_text;
270
							$desc_fmt_err_found = true;
271
						}
272
					}
273
				} else {
274
					$detail_text = sprintf(gettext("Entry added %s"), date('r'));
275
				}
276
				$address_items = explode(" ", trim($post_address));
277
				foreach ($address_items as $address_item) {
278
					$iprange_type = is_iprange($address_item);
279
					if ($iprange_type == 4) {
280
						list($startip, $endip) = explode('-', $address_item);
281
						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
						}
313
					} 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
						$final_address_details[] = $detail_text;
319
					} 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
								$input_address_subnet[] = $_POST["address_subnet"][$idx];
362
							}
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
					}
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
				if (is_subnet($input_address) ||
387
					(!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
			if ($_POST['type'] != "host" && is_ipaddr($input_address) && $input_address_subnet[$idx] != "") {
392
				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
			}
397
			$address[] = $tmpaddress;
398
		}
399
		unset($desc_fmt_err_found);
400
		if ($wrongaliases != "")
401
			$input_errors[] = sprintf(gettext('The alias(es): %s cannot be nested because they are not of the same type.'), $wrongaliases);
402
	}
403

    
404
	unset($vertical_bar_err_text);
405

    
406
	// Allow extending of the firewall edit page and include custom input validation
407
	pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/input_validation");
408

    
409
	if (!$input_errors) {
410
		$alias['address'] = is_array($address) ? implode(" ", $address) : $address;
411
		$alias['descr'] = $_POST['descr'];
412
		$alias['type'] = $_POST['type'];
413
		$alias['detail'] = implode("||", $final_address_details);
414

    
415
		/*   Check to see if alias name needs to be
416
		 *   renamed on referenced rules and such
417
		 */
418
		if ($_POST['name'] != $_POST['origname']) {
419
			// Firewall rules
420
			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
			// NAT Rules
425
			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
			// 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
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('sourceport'), $_POST['name'], $origname);
438
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('destination', 'address'), $_POST['name'], $origname);
439
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('dstport'), $_POST['name'], $origname);
440
			update_alias_names_upon_change(array('nat', 'advancedoutbound', 'rule'), array('target'), $_POST['name'], $origname);
441
			// Alias in an alias
442
			update_alias_names_upon_change(array('aliases', 'alias'), array('address'), $_POST['name'], $origname);
443
		}
444

    
445
		pfSense_handle_custom_code("/usr/local/pkg/firewall_aliases_edit/pre_write_config");
446

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

    
468
		// Sort list
469
		$a_aliases = msort($a_aliases, "name");
470

    
471
		if (write_config())
472
			mark_subsystem_dirty('aliases');
473

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

    
494
include("head.inc");
495

    
496
$network_str = gettext("Network or FQDN");
497
$networks_str = gettext("Network(s)");
498
$cidr_str = gettext("CIDR");
499
$description_str = gettext("Description");
500
$hosts_str = gettext("Host(s)");
501
$ip_str = gettext("IP or FQDN");
502
$ports_str = gettext("Port(s)");
503
$port_str = gettext("Port");
504
$url_str = gettext("URL (IPs)");
505
$url_ports_str = gettext("URL (Ports)");
506
$urltable_str = gettext("URL Table (IPs)");
507
$urltable_ports_str = gettext("URL Table (Ports)");
508
$update_freq_str = gettext("Update Freq. (days)");
509

    
510
$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

    
530
if (empty($tab)) {
531
	if (preg_match("/url/i", $pconfig['type']))
532
		$tab = 'url';
533
	else if ($pconfig['type'] == 'host')
534
		$tab = 'ip';
535
	else
536
		$tab = $pconfig['type'];
537
}
538

    
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
))->toggles();
590

    
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
	}
613

    
614
	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

    
669
include("foot.inc");
(50-50/241)