Project

General

Profile

Download (31 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * guiconfig.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2020 Rubicon Communications, LLC (Netgate)
9
 * All rights reserved.
10
 *
11
 * originally based on m0n0wall (http://m0n0.ch/wall)
12
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
13
 * All rights reserved.
14
 *
15
 * Licensed under the Apache License, Version 2.0 (the "License");
16
 * you may not use this file except in compliance with the License.
17
 * You may obtain a copy of the License at
18
 *
19
 * http://www.apache.org/licenses/LICENSE-2.0
20
 *
21
 * Unless required by applicable law or agreed to in writing, software
22
 * distributed under the License is distributed on an "AS IS" BASIS,
23
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
 * See the License for the specific language governing permissions and
25
 * limitations under the License.
26
 */
27

    
28
/* Include authentication routines */
29
/* THIS MUST BE ABOVE ALL OTHER CODE */
30
header("X-Frame-Options: SAMEORIGIN");
31
include_once('phpsessionmanager.inc');
32

    
33
function pfSense_csrf_callback() {
34
	include "csrf_error.php";
35
}
36

    
37
if (!$nocsrf) {
38
	function csrf_startup() {
39
		global $config;
40
		csrf_conf('rewrite-js', '/csrf/csrf-magic.js');
41
		$timeout_minutes = isset($config['system']['webgui']['session_timeout']) ? $config['system']['webgui']['session_timeout'] : 240;
42
		csrf_conf('expires', $timeout_minutes * 60);
43
		csrf_conf('callback', 'pfSense_csrf_callback');
44
	}
45
	require_once("csrf/csrf-magic.php");
46
	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
47
		phpsession_end(true);
48
	}
49
}
50

    
51
/* make sure nothing is cached */
52
if (!$omit_nocacheheaders) {
53
	header("Expires: 0");
54
	header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
55
	header("Cache-Control: no-cache, no-store, must-revalidate");
56
	header("Pragma: no-cache");
57
}
58

    
59
require_once("authgui.inc");
60

    
61
/* parse the configuration and include all configuration functions */
62
require_once("functions.inc");
63

    
64
/* Include the autoloader for all the GUI display classes */
65
require_once("classes/autoload.inc.php");
66

    
67
/* used by progress bar */
68
$lastseen = "-1";
69

    
70
$navlevelsep = ": ";	/* navigation level separator string */
71
$mandfldhtml = "";		/* display this before mandatory input fields */
72
$mandfldhtmlspc = "";	/* same as above, but with spacing */
73

    
74
if (!function_exists('set_language')) {
75
	require_once("pfsense-utils.inc");
76
}
77

    
78
set_language();
79

    
80
/* Some ajax scripts still need access to GUI */
81
if (!$ignorefirmwarelock) {
82
	if (is_subsystem_dirty('firmwarelock')) {
83
		if (!$d_isfwfile) {
84
			header("Location: system_update.php");
85
			exit;
86
		} else {
87
			return;
88
		}
89
	}
90
}
91

    
92
$firewall_rules_dscp_types = array(
93
	"af11",
94
	"af12",
95
	"af13",
96
	"af21",
97
	"af22",
98
	"af23",
99
	"af31",
100
	"af32",
101
	"af33",
102
	"af41",
103
	"af42",
104
	"af43",
105
	"VA",
106
	"EF",
107
	"cs1",
108
	"cs2",
109
	"cs3",
110
	"cs4",
111
	"cs5",
112
	"cs6",
113
	"cs7",
114
	"0x01",
115
	"0x02",
116
	"0x04");
117

    
118
$auth_server_types = array(
119
	'ldap' => "LDAP",
120
	'radius' => "RADIUS");
121

    
122
$ldap_urltypes = array(
123
	'TCP - Standard' => 389,
124
	'TCP - STARTTLS' => 389,
125
	'SSL - Encrypted' => 636);
126

    
127
$ldap_scopes = array(
128
	'one' => gettext("One Level"),
129
	'subtree' => gettext("Entire Subtree"));
130

    
131
$ldap_protvers = array(
132
	2,
133
	3);
134

    
135
$ldap_templates = array(
136

    
137
	'open' => array(
138
		'desc' => "OpenLDAP",
139
		'attr_user' => "cn",
140
		'attr_group' => "cn",
141
		'attr_member' => "member"),
142

    
143
	'msad' => array(
144
		'desc' => "Microsoft AD",
145
		'attr_user' => "samAccountName",
146
		'attr_group' => "cn",
147
		'attr_member' => "memberOf"),
148

    
149
	'edir' => array(
150
		'desc' => "Novell eDirectory",
151
		'attr_user' => "cn",
152
		'attr_group' => "cn",
153
		'attr_member' => "uniqueMember"));
154

    
155
$radius_srvcs = array(
156
	'both' => gettext("Authentication and Accounting"),
157
	'auth' => gettext("Authentication"),
158
	'acct' => gettext("Accounting"));
159

    
160
$radius_protocol = array(
161
	'PAP' => "PAP",
162
	'CHAP_MD5' => "MD5-CHAP",
163
	'MSCHAPv1' => "MS-CHAPv1",
164
	'MSCHAPv2' => "MS-CHAPv2");
165

    
166
$netbios_nodetypes = array(
167
	'0' => "none",
168
	'1' => "b-node",
169
	'2' => "p-node",
170
	'4' => "m-node",
171
	'8' => "h-node");
172

    
173
/* some well known ports */
174
$wkports = array(
175
	179 => "BGP",
176
	5999 => "CVSup",
177
	53 => "DNS",
178
	853 => "DNS over TLS",
179
	21 => "FTP",
180
	3000 => "HBCI",
181
	80 => "HTTP",
182
	443 => "HTTPS",
183
	5190 => "ICQ",
184
	113 => "IDENT/AUTH",
185
	143 => "IMAP",
186
	993 => "IMAP/S",
187
	4500 => "IPsec NAT-T",
188
	500 => "ISAKMP",
189
	1701 => "L2TP",
190
	389 => "LDAP",
191
	636 => "LDAP/S",
192
	1755 => "MMS/TCP",
193
	7000 => "MMS/UDP",
194
	445 => "MS DS",
195
	3389 => "MS RDP",
196
	1512 => "MS WINS",
197
	1863 => "MSN",
198
	119 => "NNTP",
199
	123 => "NTP",
200
	138 => "NetBIOS-DGM",
201
	137 => "NetBIOS-NS",
202
	139 => "NetBIOS-SSN",
203
	1194 => "OpenVPN",
204
	110 => "POP3",
205
	995 => "POP3/S",
206
	1723 => "PPTP",
207
	1812 => "RADIUS",
208
	1813 => "RADIUS accounting",
209
	5004 => "RTP",
210
	5060 => "SIP",
211
	25 => "SMTP",
212
	465 => "SMTP/S",
213
	161 => "SNMP",
214
	162 => "SNMP-Trap",
215
	22 => "SSH",
216
	3478 => "STUN",
217
	587 => "SUBMISSION",
218
	514 => "Syslog",
219
	3544 => "Teredo",
220
	23 => "Telnet",
221
	69 => "TFTP",
222
	5900 => "VNC");
223

    
224
/* TCP flags */
225
$tcpflags = array("fin", "syn", "rst", "psh", "ack", "urg", "ece", "cwr");
226

    
227
$specialnets = array(
228
	"(self)" => gettext("This Firewall"),
229
	"pppoe" => gettext("PPPoE clients"),
230
	"l2tp" => gettext("L2TP clients"));
231

    
232
$spiflist = get_configured_interface_with_descr(true);
233
foreach ($spiflist as $ifgui => $ifdesc) {
234
	$specialnets[$ifgui] = $ifdesc . " net";
235
	$specialnets[$ifgui . 'ip'] = $ifdesc . " address";
236
}
237

    
238
$medias = array(
239
	"auto" => gettext("autoselect"),
240
	"100full" => gettext("100BASE-TX full-duplex"),
241
	"100half" => gettext("100BASE-TX half-duplex"),
242
	"10full" => gettext("10BASE-T full-duplex"),
243
	"10half" => gettext("10BASE-T half-duplex"));
244

    
245
$wlan_modes = array(
246
	"bss" => gettext("Infrastructure (BSS)"),
247
	"adhoc" => gettext("Ad-hoc (IBSS)"),
248
	"hostap" => gettext("Access Point"));
249

    
250
function do_input_validation($postdata, $reqdfields, $reqdfieldsn, &$input_errors) {
251

    
252
	/* check for bad control characters */
253
	foreach ($postdata as $pn => $pd) {
254
		if (is_string($pd) && preg_match("/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/", $pd)) {
255
			$input_errors[] = sprintf(gettext("The field %s contains invalid characters."), $pn);
256
		}
257
	}
258

    
259
	if (is_array($reqdfields)) {
260
		for ($i = 0; $i < count($reqdfields); $i++) {
261
			if ($postdata[$reqdfields[$i]] == "") {
262
				$input_errors[] = sprintf(gettext("The field %s is required."), $reqdfieldsn[$i]);
263
			}
264
		}
265
	}
266
}
267

    
268
function print_input_errors($input_errors) {
269
	echo '<div class="alert alert-danger input-errors">';
270
	echo '<p>' . gettext('The following input errors were detected:') . '</p>';
271
	echo '<ul>';
272

    
273
	foreach ($input_errors as $ierr) {
274
		echo '<li>' . htmlspecialchars($ierr) . '</li>';
275
	}
276

    
277
	echo '</ul>';
278
	echo '</div>';
279
}
280

    
281
function verify_gzip_file($fname) {
282
	$returnvar = mwexec("/usr/bin/gzip -t " . escapeshellarg($fname));
283
	if ($returnvar != 0) {
284
		return 0;
285
	} else {
286
		return 1;
287
	}
288
}
289

    
290
// sprint_info_box() returns a string with a formatted informational box, it does not print the box.
291
// To format and print in one step, call print_info_box() as usual.
292
// Any required button is explicitly created, rather than relying on the detection of certain
293
// strings in the message (such as "apply"). print_info_box_np() has been exterminated.
294
// $class = the bootstrap style class (default, info, warning, success, danger)
295
// $btnname and btntext describe the optional button and its display text, the default is an 'x' Close button.
296
// Note that there is also a shortcut function print_apply_box here that creates a standard "apply" box for you.
297
// In many cases just substitute that for print_info_box_np() to easily get a warning style "Apply changes" box.
298
function sprint_info_box($msg, $class="alert-warning", $btnname = "close", $btntext = "", $btnicon = "", $btnclass = "default") {
299

    
300
	if (strpos($class, "alert-") !== 0) {
301
		$class = 'alert-' . $class;
302
	}
303

    
304
	$msg = '<div class="pull-left">' . $msg . '</div>';
305

    
306
	if ($btnname === "close") {
307
		$msg = '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' . $msg;
308
	} else if ($btnname != "") {
309
		if (empty($btntext)) {
310
			$btntext = $btnname;
311
		}
312
		if (!empty($btnicon)) {
313
			$btnicon = '<i class="fa ' . $btnicon . ' icon-embed-btn"></i>';
314
		}
315

    
316
		$msg .= '<form method="post" class="pull-right"><button type="submit" class="btn btn-' . $btnclass . '" name="'. $btnname . '" value="' . $btntext . '">' . $btnicon . $btntext . '</button>';
317

    
318
		if ( isset($_POST['if']) && !empty($_POST['if'])) {
319
			$msg .= "<input type=\"hidden\" name=\"if\" value=\"" . htmlspecialchars($_POST['if']) . "\" />";
320
		}
321

    
322
		$msg .= '</form>';
323
	}
324

    
325
	return '<div class="alert ' . $class . ' clearfix" role="alert">' . $msg . '</div>';
326
}
327

    
328
// Format and print an info box. See sprint_info_box() for details.
329
function print_info_box($msg, $class="alert-warning", $btnname = "close", $btntext = "", $btnicon = "", $btnclass = "default") {
330
	echo sprint_info_box($msg, $class, $btnname, $btntext, $btnicon, $btnclass);
331
}
332

    
333
function print_apply_box($msg) {
334
	print_info_box($msg, "warning", "apply", gettext("Apply Changes"), 'fa-check', 'success');
335
}
336

    
337
// Format and print a box reporting that changes have been applied
338
// $retval = status value from the functions called to apply the changes
339
// 0 is good
340
// non-zero is a problem
341
// $extra_text = optional extra text to display after the standard message
342
function print_apply_result_box($retval, $extra_text="") {
343
	$result_msg = get_std_save_message($retval);
344
	if ($retval === 0) {
345
		// 0 is success
346
		$severity = "success";
347
	} else {
348
		// non-zero means there was some problem
349
		$severity = "warning";
350
	}
351

    
352
	if (strlen($extra_text) > 0) {
353
		$result_msg .= " " . $extra_text;
354
	}
355
	print_info_box($result_msg, $severity);
356
}
357

    
358
/*
359
 * Print Bootstrap callout
360
 *
361
 * @param string $msg     message to display
362
 * @param string $class   contextual class, defaults to info (default | danger | warning | info)
363
 * @param string $heading optional callout heading
364
 */
365
function print_callout($msg, $class = 'info', $heading = '') {
366

    
367
	if ('' == $msg) {
368
		return;
369
	}
370
	$class = strtolower($class);
371
	$callout = '';
372

    
373
	if ($class != 'default' && $class != 'danger' && $class != 'warning' && $class != 'info') {
374
		$class = 'info';
375
	}
376
	$callout .= '<div class="bs-callout bs-callout-' . $class . '">';
377

    
378
	if ('' != $heading) {
379
		$callout .= '<h4>' . $heading . '</h4>';
380
	}
381
	$callout .= $msg . '</div>';
382
	echo $callout;
383
}
384

    
385
function get_std_save_message($retval) {
386
	$filter_related = false;
387
	$filter_pages = array("firewall_aliases", "firewall_nat", "firewall_rules", "status_logs_filter");
388
	if ($retval === 0) {
389
		// 0 is success
390
		$to_return = gettext("The changes have been applied successfully.");
391
	} else {
392
		// non-zero means there was some problem
393
		$to_return = sprintf(gettext('There was a problem applying the changes. See the %1$sSystem Logs%2$s.'), '<a href="status_logs.php">', '</a>');
394
	}
395
	foreach ($filter_pages as $fp) {
396
		if (stristr($_SERVER['SCRIPT_FILENAME'], $fp)) {
397
			$filter_related = true;
398
		}
399
	}
400
	if ($filter_related) {
401
		$to_return .= " " . gettext("The firewall rules are now reloading in the background.") . "<br />" .
402
		    sprintf(gettext('%1$sMonitor%2$s the filter reload progress.'), "<a href='status_filter_reload.php'>", "</a>");
403
	}
404
	return $to_return;
405
}
406

    
407
function pprint_address($adr) {
408
	global $specialnets;
409

    
410
	if (isset($adr['any'])) {
411
		$padr = "*";
412
	} else if ($adr['network']) {
413
		$padr = $specialnets[$adr['network']];
414
	} else {
415
		$padr = $adr['address'];
416
	}
417

    
418
	if (isset($adr['not'])) {
419
		$padr = "! " . $padr;
420
	}
421

    
422
	return $padr;
423
}
424

    
425
function pprint_port($port) {
426
	global $wkports;
427

    
428
	$pport = "";
429

    
430
	if (!$port) {
431
		return "*";
432
	} else {
433
		$srcport = explode("-", $port);
434
		if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
435
			$pport = $srcport[0];
436
			if ($wkports[$srcport[0]]) {
437
				$pport .= " (" . $wkports[$srcport[0]] . ")";
438
			}
439
		} else {
440
			$pport .= $srcport[0] . " - " . $srcport[1];
441
		}
442
	}
443

    
444
	return $pport;
445
}
446

    
447
function insert_word_breaks_in_domain_name($domain_name) {
448
	return str_replace('.', '<wbr>.', $domain_name);
449
}
450

    
451
function firewall_check_for_advanced_options(&$item) {
452
	$item_set = "";
453
	if ($item['os']) {
454
			$item_set .= "os " . htmlspecialchars($item['os']) . " ";
455
	}
456
	if ($item['dscp']) {
457
		$item_set .= "dscp " . htmlspecialchars($item['dscp']) . " ";
458
	}
459
	if ($item['max']) {
460
		$item_set .= "max " . htmlspecialchars($item['max']) . " ";
461
	}
462
	if ($item['max-src-nodes']) {
463
		$item_set .= "max-src-nodes " . htmlspecialchars($item['max-src-nodes']) . " ";
464
	}
465
	if ($item['max-src-conn']) {
466
		$item_set .= "max-src-conn " . htmlspecialchars($item['max-src-conn']) . " ";
467
	}
468
	if ($item['max-src-states']) {
469
		$item_set .= "max-src-states " . htmlspecialchars($item['max-src-states']) . " ";
470
	}
471
	if (isset($item['nopfsync'])) {
472
		$item_set .= "nopfsync ";
473
	}
474
	if ($item['statetype'] != "keep state" && $item['statetype'] != "") {
475
		$item_set .= "statetype " . htmlspecialchars($item['statetype']) . " ";
476
	}
477
	if ($item['statetimeout']) {
478
		$item_set .= "statetimeout " . htmlspecialchars($item['statetimeout']) . " ";
479
	}
480
	if (isset($item['nosync'])) {
481
		$item_set .= "no XMLRPC Sync ";
482
	}
483
	if ($item['max-src-conn-rate']) {
484
		$item_set .= "max-src-conn-rate " . htmlspecialchars($item['max-src-conn-rate']) . " ";
485
	}
486
	if ($item['max-src-conn-rates']) {
487
		$item_set .= "max-src-conn-rates " . htmlspecialchars($item['max-src-conn-rates']) . " ";
488
	}
489
	if ($item['vlanprio']) {
490
		$item_set .= "vlanprio " . htmlspecialchars($item['vlanprio']) . " ";
491
	}
492
	if ($item['vlanprioset']) {
493
		$item_set .= "vlanprioset " . htmlspecialchars($item['vlanprioset']) . " ";
494
	}
495
	if ($item['gateway']) {
496
		$item_set .= "gateway " . htmlspecialchars($item['gateway']) . " ";
497
	}
498
	if ($item['dnpipe']) {
499
		$item_set .= "limiter " . htmlspecialchars($item['dnpipe']) . " ";
500
	}
501
	if ($item['pdnpipe']) {
502
		$item_set .= "limiter " . htmlspecialchars($item['pdnpipe']) . " ";
503
	}
504
	if ($item['ackqueue']) {
505
		$item_set .= "ackqueue " . htmlspecialchars($item['ackqueue']) . " ";
506
	}
507
	if ($item['defaultqueue']) {
508
		$item_set .= "defaultqueue " . htmlspecialchars($item['defaultqueue']) . " ";
509
	}
510
	if ($item['tag']) {
511
		$item_set .= "tag " . htmlspecialchars($item['tag']) . " ";
512
	}
513
	if ($item['tagged']) {
514
		$item_set .= "tagged " . htmlspecialchars($item['tagged']) . " ";
515
	}
516
	if (isset($item['allowopts'])) {
517
		$item_set .= "allowopts ";
518
	}
519
	if (isset($item['disablereplyto'])) {
520
		$item_set .= "disable reply-to ";
521
	}
522
	if ($item['tcpflags_any'] || $item['tcpflags1'] || $item['tcpflags2']) {
523
		$item_set .= "tcpflags set";
524
	}
525

    
526
	return $item_set;
527
}
528

    
529
function gentitle($title) {
530
	global $navlevelsep;
531
	if (!is_array($title)) {
532
		return $title;
533
	} else {
534
		return join($navlevelsep, $title);
535
	}
536
}
537

    
538
function genhtmltitle($title, $links=true) {
539
	if (is_array($title)) {
540
		$num_crumbs = count($title);
541
	} else if ($title != NULL) {
542
		$num_crumbs = 1;
543
	} else {
544
		$num_crumbs = 0;
545
	}
546

    
547
	// If the array contains only one element, there are no breadcrumbs, so don't
548
	// add anything else
549
	if ($num_crumbs > 1) {
550
		$bc = '<ol class="breadcrumb">';
551

    
552
		if (!is_array($links)) {
553
			$gen_default = ($links === true);
554
			$links = array_fill(0, $num_crumbs, '');
555
			// If no links passed, then default to a link to self on the last entry.
556
			if ($gen_default) {
557
				$links[$num_crumbs-1] = '@self';
558
			}
559
		}
560

    
561
		foreach ($title as $idx => $el) {
562
			$href = $links[$idx];
563
			if (strlen($href) > 0) {
564
				// For convenience, if the caller specifies '@self' then make a link
565
				// to the current page, including any query string.
566
				if ($href == '@self') {
567
					$href = $_SERVER['REQUEST_URI'];
568
				}
569
				if (substr($href, 0, 1) != '/') {
570
					$href = '/' . $href;
571
				}
572
				$bc .= '<li><a href="' . htmlentities($href) . '">' . $el . '</a></li>';
573
			} else {
574
				$bc .= '<li>' . $el . '</li>';
575
			}
576
		}
577

    
578
		$bc .= '</ol>';
579
	} else {
580
		$bc = "";
581
	}
582

    
583
	return $bc;
584
}
585

    
586
function gen_customwidgettitle_div($widgettitle) {
587
	$divstr = '<div class="form-group">';
588
	$divstr .= '  <label for="descr" class="col-sm-4 control-label">' . gettext('Widget title'). '</label>';
589
	$divstr .= '  <div class="col-sm-4">';
590
	$divstr .= '    <input type="text" name="descr" id="descr" value="'. $widgettitle . '" class="form-control" />';
591
	$divstr .= '  </div>';
592
	$divstr .= '</div>';
593

    
594
	return $divstr;
595
}
596

    
597
function set_customwidgettitle(& $user_settings) {
598
	if ($_POST['descr']) {
599
		$user_settings['widgets'][$_POST['widgetkey']]['descr'] = trim($_POST['descr']);
600
	} else {
601
		unset($user_settings['widgets'][$_POST['widgetkey']]['descr']);
602
	}
603
}
604

    
605
/* update the changedesc and changecount(er) variables */
606
function update_changedesc($update) {
607
	global $changedesc;
608
	global $changecount;
609

    
610
	$changedesc .= " {$update}";
611
	$changecount++;
612
}
613

    
614
/* Check if variable has changed, update and log if it has
615
 * returns true if var changed
616
 * varname = variable name in plain text
617
 * orig = original value
618
 * new = new value
619
 */
620
function update_if_changed($varname, & $orig, $new) {
621
	if (is_array($orig) && is_array($new)) {
622
		$a_diff = array_diff($orig, $new);
623
		foreach ($a_diff as $diff) {
624
			update_changedesc("removed {$varname}: \"{$diff}\"");
625
		}
626
		$a_diff = array_diff($new, $orig);
627
		foreach ($a_diff as $diff) {
628
			update_changedesc("added {$varname}: \"{$diff}\"");
629
		}
630
		$orig = $new;
631
		return true;
632

    
633
	} else {
634
		if ($orig != $new) {
635
			update_changedesc("{$varname}: \"{$orig}\" -> \"{$new}\"");
636
			$orig = $new;
637
			return true;
638
		}
639
	}
640
	return false;
641
}
642

    
643
function address_to_pconfig($adr, &$padr, &$pmask, &$pnot, &$pbeginport, &$pendport) {
644
	if (isset($adr['any'])) {
645
		$padr = "any";
646
	} else if ($adr['network']) {
647
		$padr = $adr['network'];
648
	} else if ($adr['address']) {
649
		list($padr, $pmask) = explode("/", $adr['address']);
650
		if (!$pmask) {
651
			if (is_ipaddrv6($padr)) {
652
				$pmask = 128;
653
			} else {
654
				$pmask = 32;
655
			}
656
		}
657
	}
658

    
659
	if (isset($adr['not'])) {
660
		$pnot = 1;
661
	} else {
662
		$pnot = 0;
663
	}
664

    
665
	if ($adr['port']) {
666
		list($pbeginport, $pendport) = explode("-", $adr['port']);
667
		if (!$pendport) {
668
			$pendport = $pbeginport;
669
		}
670
	} else if (!is_alias($pbeginport) && !is_alias($pendport)) {
671
		$pbeginport = "any";
672
		$pendport = "any";
673
	}
674
}
675

    
676
function pconfig_to_address(&$adr, $padr, $pmask, $pnot = false, $pbeginport = 0, $pendport = 0) {
677
	$adr = array();
678

    
679
	if ($padr == "any") {
680
		$adr['any'] = true;
681
	} else if (is_specialnet($padr)) {
682
		$adr['network'] = $padr;
683
	} else {
684
		$adr['address'] = $padr;
685
		if (is_ipaddrv6($padr)) {
686
			if ($pmask != 128) {
687
				$adr['address'] .= "/" . $pmask;
688
			}
689
		} else {
690
			if ($pmask != 32) {
691
				$adr['address'] .= "/" . $pmask;
692
			}
693
		}
694
	}
695

    
696
	if ($pnot) {
697
		$adr['not'] = true;
698
	} else {
699
		unset($adr['not']);
700
	}
701

    
702
	if (($pbeginport != 0) && ($pbeginport != "any")) {
703
		if ($pbeginport != $pendport) {
704
			$adr['port'] = $pbeginport . "-" . $pendport;
705
		} else {
706
			$adr['port'] = $pbeginport;
707
		}
708
	}
709

    
710
	/*
711
	 * If the port is still unset, then it must not be numeric, but could
712
	 * be an alias or a well-known/registered service.
713
	 * See https://redmine.pfsense.org/issues/8410
714
	 */
715
	if (!isset($adr['port']) && is_port_or_alias($pbeginport)) {
716
		$adr['port'] = $pbeginport;
717
	}
718
}
719

    
720
function is_specialnet($net) {
721
	global $specialsrcdst;
722

    
723
	if (!$net) {
724
		return false;
725
	}
726
	if (in_array($net, $specialsrcdst)) {
727
		return true;
728
	} else {
729
		return false;
730
	}
731
}
732

    
733
//function to create widget tabs when called
734
function display_widget_tabs(& $tab_array) {
735
	echo "<div id=\"tabs\">";
736
	$tabscounter = 0;
737
	foreach ($tab_array as $ta) {
738
		$dashpos = strpos($ta[2], '-');
739
		$tabname = $ta[2] . "-tab";
740
		$tabclass = substr($ta[2], 0, $dashpos);
741
		$tabclass = $tabclass . "-class";
742
		if ($ta[1] == true) {
743
			$tabActive = "table-cell";
744
			$tabNonActive = "none";
745
		} else {
746
			$tabActive = "none";
747
			$tabNonActive = "table-cell";
748
		}
749
		echo "<div id=\"{$ta[2]}-active\" class=\"{$tabclass}-tabactive\" style=\"display:{$tabActive}; background-color:#EEEEEE; color:black;\">";
750
		echo "<b>&nbsp;&nbsp;&nbsp;{$ta[0]}";
751
		echo "&nbsp;&nbsp;&nbsp;</b>";
752
		echo "</div>";
753

    
754
		echo "<div id=\"{$ta[2]}-deactive\" class=\"{$tabclass}-tabdeactive\" style=\"display:{$tabNonActive}; background-color:#777777; color:white; cursor: pointer;\" onclick=\"return changeTabDIV('{$ta[2]}')\">";
755
		echo "<b>&nbsp;&nbsp;&nbsp;{$ta[0]}";
756
		echo "&nbsp;&nbsp;&nbsp;</b>";
757
		echo "</div>";
758
	}
759
	echo "</div>";
760
}
761

    
762

    
763
// Return inline javascript file or CSS to minimize
764
// request count going back to server.
765
function outputJavaScriptFileInline($javascript) {
766
	if (file_exists($javascript)) {
767
		echo "\n<script type=\"text/javascript\">\n";
768
		include_once($javascript);
769
		echo "\n</script>\n";
770
	} else {
771
		echo "\n\n<!-- Could not locate file:  {$javascript} -->\n\n";
772
	}
773
}
774

    
775

    
776

    
777
function outputCSSPrintFileInline($css) {
778
	if (file_exists($css)) {
779
		echo "\n<style media=\"print\" type=\"text/css\">\n";
780
		include_once($css);
781
		echo "\n</style>\n";
782
	} else {
783
		echo "\n\n<!-- Could not locate file:  {$css} -->\n\n";
784
	}
785
}
786

    
787

    
788
function outputCSSFileInline($css) {
789
	if (file_exists($css)) {
790
		echo "\n<style type=\"text/css\">\n";
791
		include_once($css);
792
		echo "\n</style>\n";
793
	} else {
794
		echo "\n\n<!-- Could not locate file:  {$css} -->\n\n";
795
	}
796
}
797

    
798
$rfc2616 = array(
799
	100 => "100 Continue",
800
	101 => "101 Switching Protocols",
801
	200 => "200 OK",
802
	201 => "201 Created",
803
	202 => "202 Accepted",
804
	203 => "203 Non-Authoritative Information",
805
	204 => "204 No Content",
806
	205 => "205 Reset Content",
807
	206 => "206 Partial Content",
808
	300 => "300 Multiple Choices",
809
	301 => "301 Moved Permanently",
810
	302 => "302 Found",
811
	303 => "303 See Other",
812
	304 => "304 Not Modified",
813
	305 => "305 Use Proxy",
814
	306 => "306 (Unused)",
815
	307 => "307 Temporary Redirect",
816
	400 => "400 Bad Request",
817
	401 => "401 Unauthorized",
818
	402 => "402 Payment Required",
819
	403 => "403 Forbidden",
820
	404 => "404 Not Found",
821
	405 => "405 Method Not Allowed",
822
	406 => "406 Not Acceptable",
823
	407 => "407 Proxy Authentication Required",
824
	408 => "408 Request Timeout",
825
	409 => "409 Conflict",
826
	410 => "410 Gone",
827
	411 => "411 Length Required",
828
	412 => "412 Precondition Failed",
829
	413 => "413 Request Entity Too Large",
830
	414 => "414 Request-URI Too Long",
831
	415 => "415 Unsupported Media Type",
832
	416 => "416 Requested Range Not Satisfiable",
833
	417 => "417 Expectation Failed",
834
	500 => "500 Internal Server Error",
835
	501 => "501 Not Implemented",
836
	502 => "502 Bad Gateway",
837
	503 => "503 Service Unavailable",
838
	504 => "504 Gateway Timeout",
839
	505 => "505 HTTP Version Not Supported"
840
);
841

    
842
function is_rfc2616_code($code) {
843
	global $rfc2616;
844
	if (isset($rfc2616[$code])) {
845
		return true;
846
	} else {
847
		return false;
848
	}
849
}
850

    
851
function print_rfc2616_select($tag, $current) {
852
	global $rfc2616;
853

    
854
	/* Default to 200 OK if not set */
855
	if ($current == "") {
856
		$current = 200;
857
	}
858

    
859
	echo "<select id=\"{$tag}\" name=\"{$tag}\">\n";
860
	foreach ($rfc2616 as $code => $message) {
861
		if ($code == $current) {
862
			$sel = " selected";
863
		} else {
864
			$sel = "";
865
		}
866
		echo "<option value=\"{$code}\"{$sel}>{$message}</option>\n";
867
	}
868
	echo "</select>\n";
869
}
870

    
871
// Useful debugging function, much cleaner than print_r
872
function echo_array($array, $return_me = false) {
873
	if (is_array($array) == false) {
874
		$return = "The provided variable is not an array.";
875
	} else {
876
		foreach ($array as $name=>$value) {
877
			if (is_array($value)) {
878
				$return .= "";
879
				$return .= "['<b>$name</b>'] {<div style=\"margin-left:10px;\">\n";
880
				$return .= echo_array($value, true);
881
				$return .= "</div>}";
882
				$return .= "\n\n";
883
			} else {
884
				if (is_string($value)) {
885
					$value = "\"$value\"";
886
				}
887
				$return .= "['<b>$name</b>'] = $value\n\n";
888
			}
889
		}
890
	}
891
	if ($return_me == true) {
892
		return $return;
893
	} else {
894
		echo "<pre>".$return."</pre>";
895
	}
896
}
897

    
898
/****f* pfsense-utils/display_top_tabs
899
 * NAME
900
 *	 display_top_tabs - display tabs with rounded edges
901
 * INPUTS
902
 *	 $text	  - array of tabs
903
 * RESULT
904
 *	 null
905
 ******/
906
function display_top_tabs(& $tab_array, $no_drop_down = false, $type = 'pills', $usepost = "") {
907
	global $config;
908
	global $g;
909
	global $tab_array_indent;
910
	global $tab_array_space;
911
	global $tab_array_char_limit;
912

    
913
	/*	does the user have access to this tab?
914
	 *	master user has access to everything.
915
	 *	if the user does not have access, simply
916
	 *	unset the tab item.
917
	 */
918

    
919
	/* empty string code */
920
	if ($tab_array_indent == '') {
921
		$tab_array_indent = 0;
922
	}
923

    
924
	if ($tab_array_space == '') {
925
		$tab_array_space = 1;
926
	}
927

    
928
	if ($tab_array_char_limit == '') {
929
		$tab_array_char_limit = 256;
930
	}
931

    
932
	foreach ($tab_array as $tab_id => $ta) {
933
		if (!isAllowedPage($ta[2])) {
934
			unset ($tab_array[$tab_id]);
935
		}
936
	}
937

    
938
	$tab_active_bg	 = "#EEEEEE";
939
	$tab_inactive_bg = "#777777";
940
	$nifty_tabs_corners = "#FFF";
941
	$font_color = "white";
942

    
943
	$tabcharcount = 0;
944
	foreach ($tab_array as $ta) {
945
		$tabcharcount = $tabcharcount + strlen($ta[0]);
946
	}
947

    
948
	if ($no_drop_down == true) {
949
		$tabcharcount = 0;
950
		unset($tab_array_char_limit);
951
	}
952

    
953
	// If the character count of the tab names is > 670
954
	// then show a select item dropdown menubox.
955
	if ($tabcharcount > $tab_array_char_limit) {
956
		echo gettext("Currently viewing: ");
957
		echo "<select name=\"TabSelect\" onchange=\"tabs_will_go(this)\">\n";
958

    
959
		foreach ($tab_array as $ta) {
960
			if ($ta[1] == "true") {
961
				$selected = " selected";
962
			} else {
963
				$selected = "";
964
			}
965
			// Onclick in option will not work in some browser
966
			// echo "<option onclick=\"document.location='{$ta[2]}';\"{$selected}>{$ta['0']}</option>\n";
967
			echo "<option value=\"{$ta[2]}\"{$selected}>{$ta['0']}</option>\n";
968
		}
969

    
970
		echo "</select>\n<p>&nbsp;</p>";
971
		echo "<script type=\"text/javascript\">";
972
		echo "\n//<![CDATA[\n";
973
		if ($usepost == 'usepost') {
974
			echo " function tabs_will_go(obj){ var target = obj.value.split(\"?\"); postSubmit(get2post(target[1]),target[0]); }\n";
975
		} else {
976
			echo " function tabs_will_go(obj){ document.location = obj.value; }\n";
977
		}
978
		echo "//]]>\n";
979
		echo "</script>";
980
	} else {
981
		echo '<ul class="nav nav-' . $type . '">';
982

    
983
		foreach ($tab_array as $ta) {
984
			echo '<li role="presentation"';
985
			if ($ta[1]) {
986
				echo ' class="active"';
987
			}
988

    
989
			echo '><a href="' . $ta[2] . '" ' . $usepost . '>' . $ta[0] . '</a></li>';
990
		}
991

    
992
		echo '</ul>';
993
	}
994
}
995

    
996
function add_package_tabs($tabgroup, &$tab_array) {
997
	global $config, $g;
998

    
999
	if (!isset($config['installedpackages']['package'])) {
1000
		return;
1001
	}
1002

    
1003
	foreach ($config['installedpackages']['package'] as $pkg) {
1004
		if (!is_array($pkg['tabs']['tab'])) {
1005
			continue;
1006
		}
1007

    
1008
		foreach ($pkg['tabs']['tab'] as $tab) {
1009
			if ($tab['tabgroup'] != $tabgroup) {
1010
				continue;
1011
			}
1012
			$tab_entry = array();
1013
			if ($tab['name']) {
1014
				$tab_entry[] = $tab['name'];
1015
				$tab_entry[] = false;
1016
				$tab_entry[] = $tab['url'];
1017
				$tab_array[] = $tab_entry;
1018
			}
1019
		}
1020
	}
1021
}
1022

    
1023
function alias_info_popup($alias_id) {
1024
	global $config, $user_settings;
1025

    
1026
	if (!is_array($config['aliases']['alias'][$alias_id])) {
1027
		return;
1028
	}
1029

    
1030
	$maxlength = 60;
1031
	$alias = $config['aliases']['alias'][$alias_id];
1032
	$content = "";
1033

    
1034
	if ($user_settings['webgui']['disablealiaspopupdetail']) {
1035
		if (strlen($alias['descr']) >= $maxlength) {
1036
			$alias['descr'] = substr($alias['descr'], 0, $maxlength) . '&hellip;';
1037
		}
1038

    
1039
		$content .= $alias['descr'];
1040
	} else if ($alias['url']) {
1041
		// TODO: Change it when pf supports tables with ports
1042
		if ($alias['type'] == "urltable") {
1043
			exec("/sbin/pfctl -t {$alias['name']} -T show | wc -l", $total_entries);
1044
			$counter=preg_replace("/\D/", "", $total_entries[0]);
1045
			exec("/sbin/pfctl -t {$alias['name']} -T show | head -10002", $alias_addresses);
1046
		} else {
1047
			$urlfn = alias_expand_urltable($alias['name']);
1048
			$alias_addresses = explode("\n", file_get_contents($urlfn));
1049
			$counter = count($alias_addresses);
1050
		}
1051

    
1052
		$content .= '<h5>'. $alias['url'] .'</h5><ul><li>'. implode('</li><li>', $alias_addresses) .'</li></ul>';
1053
		if ($counter > 10002) {
1054
			$content .= '<i>'. gettext("listing only first 10k items") .'</i>';
1055
		}
1056
	} else {
1057
		$alias_addresses = explode (" ", $alias['address']);
1058
		$alias_details = explode ("||", $alias['detail']);
1059
		$idx = 0;
1060

    
1061
		$content .= "<table>\n";
1062
		$content .= "<thead>\n";
1063
		$content .= "<tr>\n";
1064
		$content .= "<th>" . gettext("Value") . "</th><th  style='padding-left: 10px;'>" . gettext("Description") . "</th></tr>\n";
1065
		$content .= "</thead>\n";
1066
		$content .= "<tbody>\n";
1067

    
1068
		foreach ($alias_addresses as $ap) {
1069
			$content .= "	<tr>\n";
1070
			$content .= "		<td>\n";
1071
			$content .= 			$ap;
1072
			$content .=	"		</td>\n";
1073
			$content .= "		<td style='padding-left: 10px;'>\n";
1074
			$content .= 			htmlspecialchars($alias_details[$idx]);
1075
			$content .=	"		</td>\n";
1076
			$content .= "	</tr>\n";
1077
			$idx++;
1078
		}
1079

    
1080
		$content .= "</tbody>\n";
1081
		$content .= "<table>\n";
1082
	}
1083

    
1084
	return $content;
1085
}
1086

    
1087
function rule_columns_with_alias($src, $srcport, $dst, $dstport, $target="", $targetport="") {
1088
	global $config;
1089

    
1090
	if ($config['aliases']['alias'] == "" || !is_array($config['aliases']['alias'])) {
1091
		return;
1092
	}
1093

    
1094
	$columns = array();
1095
	foreach ($config['aliases']['alias'] as $alias_id => $alias_name) {
1096
		if ($alias_name['name'] == $src) {
1097
			$columns['src'] = $alias_id;
1098
		}
1099
		if ($alias_name['name'] == $srcport) {
1100
			$columns['srcport'] = $alias_id;
1101
		}
1102
		if ($alias_name['name'] == $dst) {
1103
			$columns['dst'] = $alias_id;
1104
		}
1105
		if ($alias_name['name'] == $dstport) {
1106
			$columns['dstport'] = $alias_id;
1107
		}
1108
		if ($alias_name['name'] == $target) {
1109
			$columns['target'] = $alias_id;
1110
		}
1111
		if ($alias_name['name'] == $targetport) {
1112
			$columns['targetport'] = $alias_id;
1113
		}
1114
	}
1115

    
1116
	return $columns;
1117
}
1118

    
1119
function form_output_row($name, $label, $content) {
1120
var_dump($content);die;
1121
?>
1122
<div class="form-group">
1123
	<label for="<?=$name?>" class="col-sm-2 control-label"><?=gettext($label); ?></label>
1124
	<div class="col-sm-10">
1125
		<?=$content?>
1126
	</div>
1127
</div>
1128
<?php
1129
}
1130

    
1131
function set_flash_message($class, $msg) {
1132
	@phpsession_begin();
1133
	$_SESSION['flash_messages'][$class][] = $msg;
1134
	@phpsession_end(true);
1135
}
1136

    
1137
function get_flash_message() {
1138
	@phpsession_begin();
1139
	if (isset($_SESSION['flash_messages']) && !empty($_SESSION['flash_messages'])) {
1140
		foreach ($_SESSION['flash_messages'] as $class => $flash_message) {
1141
			print_info_box(implode("<br />", $flash_message), $class);
1142
		}
1143
		unset($_SESSION['flash_messages']);
1144
	}
1145
	@phpsession_end(true);
1146
}
1147

    
1148
/* Retrieve GET or POST Value/State
1149
 * Eample Usage:
1150
 * $value = getGETPOSTsettingvalue('get/post parameter name', "");
1151
 * $value = getGETPOSTsettingvalue('get/post parameter name', null);
1152
 * $state = getGETPOSTsettingvalue('get/post parameter name', null);
1153
 * $state = getGETPOSTsettingvalue('get/post parameter name', false);
1154
 */
1155
function getGETPOSTsettingvalue($settingname, $default) {
1156
	$settingvalue = $default;
1157
	if ($_GET[$settingname]) {
1158
		$settingvalue = $_GET[$settingname];
1159
	}
1160
	if ($_POST[$settingname]) {
1161
		$settingvalue = $_POST[$settingname];
1162
	}
1163
	return $settingvalue;
1164
}
1165

    
1166
/* set timezone */
1167
if (isset($config['system']['timezone']) &&
1168
    !empty($config['system']['timezone'])) {
1169
	$timezone = $config['system']['timezone'];
1170
} elseif (isset($g['default_timezone']) && !empty($g['default_timezone'])) {
1171
	$timezone = $g['default_timezone'];
1172
} else {
1173
	$timezone = "Etc/UTC";
1174
}
1175

    
1176
/* Remove files we do not want to see in a crash report */
1177
function cleanup_crash_file_list() {
1178
	$files = glob("/var/crash/*");
1179
	if (!is_array($files) || empty($files)) {
1180
		return array();
1181
	}
1182

    
1183
	$exclude_patterns = array(
1184
		'.*.last',
1185
		'bounds',
1186
		'minfree'
1187
	);
1188

    
1189
	foreach ($files as $idx => $fb) {
1190
		if (preg_match('/' . implode('|', $exclude_patterns) . '/', basename($fb)) == 1) {
1191
			unset($files[$idx]);
1192
		}
1193
	}
1194

    
1195
	return $files;
1196
}
1197

    
1198
function system_has_crash_data() {
1199
	/* Test if there are any crash data files present */
1200
	return count(cleanup_crash_file_list()) > 0;
1201
}
1202

    
1203
function system_has_php_errors() {
1204
	/* Check if the PHP error log is empty. Cast to int in case the file
1205
	 * does not exist and filesize() returns false. */
1206
	return (int) @filesize("/tmp/PHP_errors.log") > 0;
1207
}
1208

    
1209
date_default_timezone_set($timezone);
1210

    
1211
?>
(67-67/227)