Project

General

Profile

Download (33.3 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-2023 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
include_once("util.inc");
33

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

    
38
if (!$nocsrf) {
39
	function csrf_startup() {
40
		csrf_conf('rewrite-js', '/csrf/csrf-magic.js');
41
		/* Loading the configuration to get this value breaks other
42
		 * functions. See https://redmine.pfsense.org/issues/13757 */
43
		// $timeout_minutes = config_get_path('system/webgui/session_timeout', 240);
44
		$timeout_minutes = 240;
45
		csrf_conf('expires', $timeout_minutes * 60);
46
		csrf_conf('callback', 'pfSense_csrf_callback');
47
	}
48
	require_once("csrf/csrf-magic.php");
49
	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
50
		phpsession_end(true);
51
	}
52
}
53

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

    
62
require_once("authgui.inc");
63
/* Load config.inc after authgui.inc
64
 * See https://redmine.pfsense.org/issues/13757 */
65
include_once('config.inc');
66
include_once('config.lib.inc');
67

    
68
/* parse the configuration and include all configuration functions */
69
require_once("functions.inc");
70

    
71
/* Include the autoloader for all the GUI display classes */
72
require_once("classes/autoload.inc.php");
73

    
74
/* used by progress bar */
75
$lastseen = "-1";
76

    
77
$navlevelsep = ": ";	/* navigation level separator string */
78
$mandfldhtml = "";		/* display this before mandatory input fields */
79
$mandfldhtmlspc = "";	/* same as above, but with spacing */
80

    
81
if (!function_exists('set_language')) {
82
	require_once("pfsense-utils.inc");
83
}
84

    
85
set_language();
86

    
87
/* Some ajax scripts still need access to GUI */
88
if (!$ignorefirmwarelock) {
89
	if (is_subsystem_dirty('firmwarelock')) {
90
		if (!$d_isfwfile) {
91
			header("Location: system_update.php");
92
			exit;
93
		} else {
94
			return;
95
		}
96
	}
97
}
98

    
99
$firewall_rules_dscp_types = array(
100
	"af11",
101
	"af12",
102
	"af13",
103
	"af21",
104
	"af22",
105
	"af23",
106
	"af31",
107
	"af32",
108
	"af33",
109
	"af41",
110
	"af42",
111
	"af43",
112
	"VA",
113
	"EF",
114
	"cs1",
115
	"cs2",
116
	"cs3",
117
	"cs4",
118
	"cs5",
119
	"cs6",
120
	"cs7",
121
	"0x01",
122
	"0x02",
123
	"0x04");
124

    
125
$auth_server_types = array(
126
	'ldap' => "LDAP",
127
	'radius' => "RADIUS");
128

    
129
$ldap_urltypes = array(
130
	'Standard TCP' => 389,
131
	'STARTTLS Encrypted' => 389,
132
	'SSL/TLS Encrypted' => 636);
133

    
134
$ldap_scopes = array(
135
	'one' => gettext("One Level"),
136
	'subtree' => gettext("Entire Subtree"));
137

    
138
$ldap_protvers = array(
139
	2,
140
	3);
141

    
142
$ldap_templates = array(
143

    
144
	'open' => array(
145
		'desc' => "OpenLDAP",
146
		'attr_user' => "cn",
147
		'attr_group' => "cn",
148
		'attr_member' => "member",
149
		'allow_unauthenticated' => "true"),
150

    
151
	'msad' => array(
152
		'desc' => "Microsoft AD",
153
		'attr_user' => "samAccountName",
154
		'attr_group' => "cn",
155
		'attr_member' => "memberOf",
156
		'allow_unauthenticated' => "false"),
157

    
158
	'edir' => array(
159
		'desc' => "Novell eDirectory",
160
		'attr_user' => "cn",
161
		'attr_group' => "cn",
162
		'attr_member' => "uniqueMember",
163
		'allow_unauthenticated' => "false"));
164

    
165
$radius_srvcs = array(
166
	'both' => gettext("Authentication and Accounting"),
167
	'auth' => gettext("Authentication"),
168
	'acct' => gettext("Accounting"));
169

    
170
$radius_protocol = array(
171
	'PAP' => "PAP",
172
	'CHAP_MD5' => "MD5-CHAP",
173
	'MSCHAPv1' => "MS-CHAPv1",
174
	'MSCHAPv2' => "MS-CHAPv2");
175

    
176
$netbios_nodetypes = array(
177
	'0' => "none",
178
	'1' => "b-node",
179
	'2' => "p-node",
180
	'4' => "m-node",
181
	'8' => "h-node");
182

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

    
234
/* TCP flags */
235
$tcpflags = array("fin", "syn", "rst", "psh", "ack", "urg", "ece", "cwr");
236

    
237
$specialnets = array(
238
	"(self)" => gettext("This Firewall"),
239
	"pppoe" => gettext("PPPoE clients"),
240
	"l2tp" => gettext("L2TP clients"));
241

    
242
$spiflist = get_configured_interface_with_descr(true);
243
foreach ($spiflist as $ifgui => $ifdesc) {
244
	$specialnets[$ifgui] = $ifdesc . " net";
245
	$specialnets[$ifgui . 'ip'] = $ifdesc . " address";
246
}
247

    
248
$medias = array(
249
	"auto" => gettext("autoselect"),
250
	"100full" => gettext("100BASE-TX full-duplex"),
251
	"100half" => gettext("100BASE-TX half-duplex"),
252
	"10full" => gettext("10BASE-T full-duplex"),
253
	"10half" => gettext("10BASE-T half-duplex"));
254

    
255
$wlan_modes = array(
256
	"bss" => gettext("Infrastructure (BSS)"),
257
	"adhoc" => gettext("Ad-hoc (IBSS)"),
258
	"hostap" => gettext("Access Point"));
259

    
260
function do_input_validation($postdata, $reqdfields, $reqdfieldsn, &$input_errors) {
261

    
262
	/* check for bad control characters */
263
	foreach ($postdata as $pn => $pd) {
264
		if (is_string($pd) && preg_match("/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/", $pd)) {
265
			$input_errors[] = sprintf(gettext("The field %s contains invalid characters."), $pn);
266
		}
267
	}
268

    
269
	if (is_array($reqdfields)) {
270
		for ($i = 0; $i < count($reqdfields); $i++) {
271
			if ($postdata[$reqdfields[$i]] == "") {
272
				$input_errors[] = sprintf(gettext("The field %s is required."), $reqdfieldsn[$i]);
273
			}
274
		}
275
	}
276
}
277

    
278
function print_input_errors($input_errors) {
279
	echo '<div class="alert alert-danger input-errors">';
280
	echo '<p>' . gettext('The following input errors were detected:') . '</p>';
281
	echo '<ul>';
282

    
283
	foreach ($input_errors as $ierr) {
284
		echo '<li>' . htmlspecialchars($ierr) . '</li>';
285
	}
286

    
287
	echo '</ul>';
288
	echo '</div>';
289
}
290

    
291
function verify_gzip_file($fname) {
292
	$returnvar = mwexec("/usr/bin/gzip -t " . escapeshellarg($fname));
293
	if ($returnvar != 0) {
294
		return 0;
295
	} else {
296
		return 1;
297
	}
298
}
299

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

    
310
	if (strpos($class, "alert-") !== 0) {
311
		$class = 'alert-' . $class;
312
	}
313

    
314
	$msg = '<div class="pull-left">' . $msg . '</div>';
315

    
316
	if ($btnname === "close") {
317
		$msg = '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' . $msg;
318
	} else if ($btnname != "") {
319
		if (empty($btntext)) {
320
			$btntext = $btnname;
321
		}
322
		if (!empty($btnicon)) {
323
			$btnicon = '<i class="fa ' . $btnicon . ' icon-embed-btn"></i>';
324
		}
325

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

    
328
		if ( isset($_POST['if']) && !empty($_POST['if'])) {
329
			$msg .= "<input type=\"hidden\" name=\"if\" value=\"" . htmlspecialchars($_POST['if']) . "\" />";
330
		}
331

    
332
		$msg .= '</form>';
333
	}
334

    
335
	return '<div class="alert ' . $class . ' clearfix" role="alert">' . $msg . '</div>';
336
}
337

    
338
// Format and print an info box. See sprint_info_box() for details.
339
function print_info_box($msg, $class="alert-warning", $btnname = "close", $btntext = "", $btnicon = "", $btnclass = "default") {
340
	echo sprint_info_box($msg, $class, $btnname, $btntext, $btnicon, $btnclass);
341
}
342

    
343
function print_apply_box($msg) {
344
	print_info_box($msg, "warning", "apply", gettext("Apply Changes"), 'fa-check', 'success');
345
}
346

    
347
// Format and print a box reporting that changes have been applied
348
// $retval = status value from the functions called to apply the changes
349
// 0 is good
350
// non-zero is a problem
351
// $extra_text = optional extra text to display after the standard message
352
function print_apply_result_box($retval, $extra_text="") {
353
	$result_msg = get_std_save_message($retval);
354
	if ($retval === 0) {
355
		// 0 is success
356
		$severity = "success";
357
	} else {
358
		// non-zero means there was some problem
359
		$severity = "warning";
360
	}
361

    
362
	if (strlen($extra_text) > 0) {
363
		$result_msg .= " " . $extra_text;
364
	}
365
	print_info_box($result_msg, $severity);
366
}
367

    
368
/*
369
 * Print Bootstrap callout
370
 *
371
 * @param string $msg     message to display
372
 * @param string $class   contextual class, defaults to info (default | danger | warning | info)
373
 * @param string $heading optional callout heading
374
 */
375
function print_callout($msg, $class = 'info', $heading = '') {
376

    
377
	if ('' == $msg) {
378
		return;
379
	}
380
	$class = strtolower($class);
381
	$callout = '';
382

    
383
	if ($class != 'default' && $class != 'danger' && $class != 'warning' && $class != 'info') {
384
		$class = 'info';
385
	}
386
	$callout .= '<div class="bs-callout bs-callout-' . $class . '">';
387

    
388
	if ('' != $heading) {
389
		$callout .= '<h4>' . $heading . '</h4>';
390
	}
391
	$callout .= $msg . '</div>';
392
	echo $callout;
393
}
394

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

    
417
function pprint_address($adr) {
418
	global $specialnets;
419

    
420
	if (isset($adr['any'])) {
421
		$padr = "*";
422
	} else if ($adr['network']) {
423
		$padr = $specialnets[$adr['network']];
424
	} else {
425
		$padr = $adr['address'];
426
	}
427

    
428
	if (isset($adr['not'])) {
429
		$padr = "! " . $padr;
430
	}
431

    
432
	return $padr;
433
}
434

    
435
function pprint_port($port) {
436
	global $wkports;
437

    
438
	$pport = "";
439

    
440
	if (!$port) {
441
		return "*";
442
	} else {
443
		$srcport = explode("-", $port);
444
		if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
445
			$pport = $srcport[0];
446
			if ($wkports[$srcport[0]]) {
447
				$pport .= " (" . $wkports[$srcport[0]] . ")";
448
			}
449
		} else {
450
			$pport .= $srcport[0] . " - " . $srcport[1];
451
		}
452
	}
453

    
454
	return $pport;
455
}
456

    
457
function insert_word_breaks_in_domain_name($domain_name) {
458
	return str_replace('.', '<wbr>.', $domain_name);
459
}
460

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

    
536
	return $item_set;
537
}
538

    
539
function gentitle($title) {
540
	global $navlevelsep;
541
	if (!is_array($title)) {
542
		return $title;
543
	} else {
544
		return join($navlevelsep, $title);
545
	}
546
}
547

    
548
function genhtmltitle($title, $links=true) {
549
	if (is_array($title)) {
550
		$num_crumbs = count($title);
551
	} else if ($title != NULL) {
552
		$num_crumbs = 1;
553
	} else {
554
		$num_crumbs = 0;
555
	}
556

    
557
	// If the array contains only one element, there are no breadcrumbs, so don't
558
	// add anything else
559
	if ($num_crumbs > 1) {
560
		$bc = '<ol class="breadcrumb">';
561

    
562
		if (!is_array($links)) {
563
			$gen_default = ($links === true);
564
			$links = array_fill(0, $num_crumbs, '');
565
			// If no links passed, then default to a link to self on the last entry.
566
			if ($gen_default) {
567
				$links[$num_crumbs-1] = '@self';
568
			}
569
		}
570

    
571
		foreach ($title as $idx => $el) {
572
			$href = $links[$idx];
573
			if (strlen($href) > 0) {
574
				// For convenience, if the caller specifies '@self' then make a link
575
				// to the current page, including any query string.
576
				if ($href == '@self') {
577
					$href = $_SERVER['REQUEST_URI'];
578
				}
579
				if (substr($href, 0, 1) != '/') {
580
					$href = '/' . $href;
581
				}
582
				$bc .= '<li><a href="' . htmlentities($href) . '">' . $el . '</a></li>';
583
			} else {
584
				$bc .= '<li>' . $el . '</li>';
585
			}
586
		}
587

    
588
		$bc .= '</ol>';
589
	} else {
590
		$bc = "";
591
	}
592

    
593
	return $bc;
594
}
595

    
596
function gen_customwidgettitle_div($widgettitle) {
597
	$divstr = '<div class="form-group">';
598
	$divstr .= '  <label for="descr" class="col-sm-4 control-label">' . gettext('Widget title'). '</label>';
599
	$divstr .= '  <div class="col-sm-4">';
600
	$divstr .= '    <input type="text" name="descr" id="descr" value="'. $widgettitle . '" class="form-control" />';
601
	$divstr .= '  </div>';
602
	$divstr .= '</div>';
603

    
604
	return $divstr;
605
}
606

    
607
function set_customwidgettitle(& $user_settings) {
608
	if ($_POST['descr']) {
609
		$user_settings['widgets'][$_POST['widgetkey']]['descr'] = trim($_POST['descr']);
610
	} else {
611
		unset($user_settings['widgets'][$_POST['widgetkey']]['descr']);
612
	}
613
}
614

    
615
/* update the changedesc and changecount(er) variables */
616
function update_changedesc($update) {
617
	global $changedesc;
618
	global $changecount;
619

    
620
	$changedesc .= " {$update}";
621
	$changecount++;
622
}
623

    
624
/* Check if variable has changed, update and log if it has
625
 * returns true if var changed
626
 * varname = variable name in plain text
627
 * orig = original value
628
 * new = new value
629
 */
630
function update_if_changed($varname, & $orig, $new) {
631
	if (is_array($orig) && is_array($new)) {
632
		$a_diff = array_diff($orig, $new);
633
		foreach ($a_diff as $diff) {
634
			update_changedesc("removed {$varname}: \"{$diff}\"");
635
		}
636
		$a_diff = array_diff($new, $orig);
637
		foreach ($a_diff as $diff) {
638
			update_changedesc("added {$varname}: \"{$diff}\"");
639
		}
640
		$orig = $new;
641
		return true;
642

    
643
	} else {
644
		if ($orig != $new) {
645
			update_changedesc("{$varname}: \"{$orig}\" -> \"{$new}\"");
646
			$orig = $new;
647
			return true;
648
		}
649
	}
650
	return false;
651
}
652

    
653
//function to create widget tabs when called
654
function display_widget_tabs(& $tab_array) {
655
	echo "<div id=\"tabs\">";
656
	foreach ($tab_array as $ta) {
657
		$dashpos = strpos($ta[2], '-');
658
		$tabclass = substr($ta[2], 0, $dashpos);
659
		$tabclass = $tabclass . "-class";
660
		if ($ta[1] == true) {
661
			$tabActive = "table-cell";
662
			$tabNonActive = "none";
663
		} else {
664
			$tabActive = "none";
665
			$tabNonActive = "table-cell";
666
		}
667
		echo "<div id=\"{$ta[2]}-active\" class=\"{$tabclass}-tabactive\" style=\"display:{$tabActive}; background-color:#EEEEEE; color:black;\">";
668
		echo "<b>&nbsp;&nbsp;&nbsp;{$ta[0]}";
669
		echo "&nbsp;&nbsp;&nbsp;</b>";
670
		echo "</div>";
671

    
672
		echo "<div id=\"{$ta[2]}-deactive\" class=\"{$tabclass}-tabdeactive\" style=\"display:{$tabNonActive}; background-color:#777777; color:white; cursor: pointer;\" onclick=\"return changeTabDIV('{$ta[2]}')\">";
673
		echo "<b>&nbsp;&nbsp;&nbsp;{$ta[0]}";
674
		echo "&nbsp;&nbsp;&nbsp;</b>";
675
		echo "</div>";
676
	}
677
	echo "</div>";
678
}
679

    
680
// Return inline javascript file or CSS to minimize
681
// request count going back to server.
682
function outputJavaScriptFileInline($javascript) {
683
	if (file_exists($javascript)) {
684
		echo "\n<script type=\"text/javascript\">\n";
685
		include_once($javascript);
686
		echo "\n</script>\n";
687
	} else {
688
		echo "\n\n<!-- Could not locate file:  {$javascript} -->\n\n";
689
	}
690
}
691

    
692
function outputCSSPrintFileInline($css) {
693
	if (file_exists($css)) {
694
		echo "\n<style media=\"print\" type=\"text/css\">\n";
695
		include_once($css);
696
		echo "\n</style>\n";
697
	} else {
698
		echo "\n\n<!-- Could not locate file:  {$css} -->\n\n";
699
	}
700
}
701

    
702
function outputCSSFileInline($css) {
703
	if (file_exists($css)) {
704
		echo "\n<style type=\"text/css\">\n";
705
		include_once($css);
706
		echo "\n</style>\n";
707
	} else {
708
		echo "\n\n<!-- Could not locate file:  {$css} -->\n\n";
709
	}
710
}
711

    
712
$rfc2616 = array(
713
	100 => "100 Continue",
714
	101 => "101 Switching Protocols",
715
	200 => "200 OK",
716
	201 => "201 Created",
717
	202 => "202 Accepted",
718
	203 => "203 Non-Authoritative Information",
719
	204 => "204 No Content",
720
	205 => "205 Reset Content",
721
	206 => "206 Partial Content",
722
	300 => "300 Multiple Choices",
723
	301 => "301 Moved Permanently",
724
	302 => "302 Found",
725
	303 => "303 See Other",
726
	304 => "304 Not Modified",
727
	305 => "305 Use Proxy",
728
	306 => "306 (Unused)",
729
	307 => "307 Temporary Redirect",
730
	400 => "400 Bad Request",
731
	401 => "401 Unauthorized",
732
	402 => "402 Payment Required",
733
	403 => "403 Forbidden",
734
	404 => "404 Not Found",
735
	405 => "405 Method Not Allowed",
736
	406 => "406 Not Acceptable",
737
	407 => "407 Proxy Authentication Required",
738
	408 => "408 Request Timeout",
739
	409 => "409 Conflict",
740
	410 => "410 Gone",
741
	411 => "411 Length Required",
742
	412 => "412 Precondition Failed",
743
	413 => "413 Request Entity Too Large",
744
	414 => "414 Request-URI Too Long",
745
	415 => "415 Unsupported Media Type",
746
	416 => "416 Requested Range Not Satisfiable",
747
	417 => "417 Expectation Failed",
748
	500 => "500 Internal Server Error",
749
	501 => "501 Not Implemented",
750
	502 => "502 Bad Gateway",
751
	503 => "503 Service Unavailable",
752
	504 => "504 Gateway Timeout",
753
	505 => "505 HTTP Version Not Supported"
754
);
755

    
756
function is_rfc2616_code($code) {
757
	global $rfc2616;
758
	if (isset($rfc2616[$code])) {
759
		return true;
760
	} else {
761
		return false;
762
	}
763
}
764

    
765
function print_rfc2616_select($tag, $current) {
766
	global $rfc2616;
767

    
768
	/* Default to 200 OK if not set */
769
	if ($current == "") {
770
		$current = 200;
771
	}
772

    
773
	echo "<select id=\"{$tag}\" name=\"{$tag}\">\n";
774
	foreach ($rfc2616 as $code => $message) {
775
		if ($code == $current) {
776
			$sel = " selected";
777
		} else {
778
			$sel = "";
779
		}
780
		echo "<option value=\"{$code}\"{$sel}>{$message}</option>\n";
781
	}
782
	echo "</select>\n";
783
}
784

    
785
// Useful debugging function, much cleaner than print_r
786
function echo_array($array, $return_me = false) {
787
	$return = "";
788
	if (is_array($array) == false) {
789
		$return = "The provided variable is not an array.";
790
	} else {
791
		foreach ($array as $name=>$value) {
792
			if (is_array($value)) {
793
				$return .= "";
794
				$return .= "['<b>$name</b>'] {<div style=\"margin-left:10px;\">\n";
795
				$return .= echo_array($value, true);
796
				$return .= "</div>}";
797
				$return .= "\n\n";
798
			} else {
799
				if (is_string($value)) {
800
					$value = "\"$value\"";
801
				}
802
				$return .= "['<b>$name</b>'] = $value\n\n";
803
			}
804
		}
805
	}
806
	if ($return_me == true) {
807
		return $return;
808
	} else {
809
		echo "<pre>".$return."</pre>";
810
	}
811
}
812

    
813
/****f* pfsense-utils/display_top_tabs
814
 * NAME
815
 *	 display_top_tabs - display tabs with rounded edges
816
 * INPUTS
817
 *	 $text	  - array of tabs
818
 * RESULT
819
 *	 null
820
 ******/
821
function display_top_tabs(& $tab_array, $no_drop_down = false, $type = 'pills', $usepost = "") {
822
	global $tab_array_indent;
823
	global $tab_array_space;
824
	global $tab_array_char_limit;
825

    
826
	/*	does the user have access to this tab?
827
	 *	master user has access to everything.
828
	 *	if the user does not have access, simply
829
	 *	unset the tab item.
830
	 */
831

    
832
	/* empty string code */
833
	if ($tab_array_indent == '') {
834
		$tab_array_indent = 0;
835
	}
836

    
837
	if ($tab_array_space == '') {
838
		$tab_array_space = 1;
839
	}
840

    
841
	if ($tab_array_char_limit == '') {
842
		$tab_array_char_limit = 256;
843
	}
844

    
845
	foreach ($tab_array as $tab_id => $ta) {
846
		if (!isAllowedPage($ta[2])) {
847
			unset ($tab_array[$tab_id]);
848
		}
849
	}
850

    
851
	$tabcharcount = 0;
852
	foreach ($tab_array as $ta) {
853
		$tabcharcount = $tabcharcount + strlen($ta[0]);
854
	}
855

    
856
	if ($no_drop_down == true) {
857
		$tabcharcount = 0;
858
		unset($tab_array_char_limit);
859
	}
860

    
861
	// If the character count of the tab names is > 670
862
	// then show a select item dropdown menubox.
863
	if ($tabcharcount > $tab_array_char_limit) {
864
		echo gettext("Currently viewing: ");
865
		echo "<select name=\"TabSelect\" onchange=\"tabs_will_go(this)\">\n";
866

    
867
		foreach ($tab_array as $ta) {
868
			if ($ta[1] == "true") {
869
				$selected = " selected";
870
			} else {
871
				$selected = "";
872
			}
873
			// Onclick in option will not work in some browser
874
			// echo "<option onclick=\"document.location='{$ta[2]}';\"{$selected}>{$ta['0']}</option>\n";
875
			echo "<option value=\"{$ta[2]}\"{$selected}>{$ta['0']}</option>\n";
876
		}
877

    
878
		echo "</select>\n<p>&nbsp;</p>";
879
		echo "<script type=\"text/javascript\">";
880
		echo "\n//<![CDATA[\n";
881
		if ($usepost == 'usepost') {
882
			echo " function tabs_will_go(obj){ var target = obj.value.split(\"?\"); postSubmit(get2post(target[1]),target[0]); }\n";
883
		} else {
884
			echo " function tabs_will_go(obj){ document.location = obj.value; }\n";
885
		}
886
		echo "//]]>\n";
887
		echo "</script>";
888
	} else {
889
		echo '<ul class="nav nav-' . $type . '">';
890

    
891
		foreach ($tab_array as $ta) {
892
			echo '<li role="presentation"';
893
			if ($ta[1]) {
894
				echo ' class="active"';
895
			}
896

    
897
			echo '><a href="' . $ta[2] . '" ' . $usepost . '>' . $ta[0] . '</a></li>';
898
		}
899

    
900
		echo '</ul>';
901
	}
902
}
903

    
904
function add_package_tabs($tabgroup, &$tab_array) {
905
	foreach (config_get_path('installedpackages/package', []) as $pkg) {
906
		if (!is_array($pkg['tabs']['tab'])) {
907
			continue;
908
		}
909

    
910
		foreach ($pkg['tabs']['tab'] as $tab) {
911
			if ($tab['tabgroup'] != $tabgroup) {
912
				continue;
913
			}
914
			$tab_entry = array();
915
			if ($tab['name']) {
916
				$tab_entry[] = $tab['name'];
917
				$tab_entry[] = false;
918
				$tab_entry[] = $tab['url'];
919
				$tab_array[] = $tab_entry;
920
			}
921
		}
922
	}
923
}
924

    
925
function alias_info_popup($alias_id) {
926
	global $user_settings;
927

    
928
	$alias = config_get_path("aliases/alias/{$alias_id}");
929
	if (!is_array($alias)) {
930
		return;
931
	}
932

    
933
	$maxlength = 60;
934
	$content = "";
935

    
936
	if ($user_settings['webgui']['disablealiaspopupdetail']) {
937
		if (strlen($alias['descr']) >= $maxlength) {
938
			$alias['descr'] = substr($alias['descr'], 0, $maxlength) . '&hellip;';
939
		}
940

    
941
		$content .= $alias['descr'];
942
	} else if ($alias['url']) {
943
		// TODO: Change it when pf supports tables with ports
944
		if ($alias['type'] == "urltable") {
945
			exec("/sbin/pfctl -t {$alias['name']} -T show | wc -l", $total_entries);
946
			$counter=preg_replace("/\D/", "", $total_entries[0]);
947
			exec("/sbin/pfctl -t {$alias['name']} -T show | head -10002", $alias_addresses);
948
		} else {
949
			$urlfn = alias_expand_urltable($alias['name']);
950
			$alias_addresses = explode("\n", file_get_contents($urlfn));
951
			$counter = count($alias_addresses);
952
		}
953

    
954
		$content .= '<h5>'. htmlspecialchars($alias['url']) .'</h5><ul><li>'. implode('</li><li>', $alias_addresses) .'</li></ul>';
955
		if ($counter > 10002) {
956
			$content .= '<i>'. gettext("listing only first 10k items") .'</i>';
957
		}
958
	} else {
959
		$alias_addresses = explode (" ", $alias['address']);
960
		$alias_details = explode ("||", $alias['detail']);
961
		$idx = 0;
962

    
963
		$content .= "<table>\n";
964
		$content .= "<thead>\n";
965
		$content .= "<tr>\n";
966
		$content .= "<th>" . gettext("Value") . "</th><th  style='padding-left: 10px;'>" . gettext("Description") . "</th></tr>\n";
967
		$content .= "</thead>\n";
968
		$content .= "<tbody>\n";
969

    
970
		foreach ($alias_addresses as $ap) {
971
			$content .= "	<tr>\n";
972
			$content .= "		<td>\n";
973
			$content .= 			alias_idn_to_utf8($ap);
974
			$content .=	"		</td>\n";
975
			$content .= "		<td style='padding-left: 10px;'>\n";
976
			$content .= 			htmlspecialchars($alias_details[$idx]);
977
			$content .=	"		</td>\n";
978
			$content .= "	</tr>\n";
979
			$idx++;
980
		}
981

    
982
		$content .= "</tbody>\n";
983
		$content .= "</table>\n";
984
	}
985

    
986
	return $content;
987
}
988

    
989
function gateway_info_popup($showgw, $gateways_status = false) {
990
	init_config_arr(array('gateways', 'gateway_group'));
991
	/* Get groups indexed by name so we can avoid re-scanning the array
992
	 * multiple times later unnecessarily. */
993
	$a_gateways = return_gateways_array(true, false, true, false);
994

    
995
	/* Use cached gateway status if available.
996
	 * See https://redmine.pfsense.org/issues/12174 */
997
	if (!is_array($gateways_status)) {
998
		$gateways_status = return_gateways_status(true);
999
	}
1000

    
1001
	$content = "";
1002
	$gws = array();
1003
	$bgdanger = array('force_down', 'down', 'highloss', 'highdelay');
1004
	$bgwarning = array('loss', 'delay');
1005
	$bgsuccess = array('online', 'none');
1006
	$bgcolor = "bg-info";
1007
	$link = "";
1008

    
1009
	if (is_array($a_gateways)) {
1010
		/* Since gw array is hashed by name, we need to count the
1011
		 * index number manually for links since those are by position.
1012
		 */
1013
		$i = 0;
1014
		foreach ($a_gateways as $gateway) {
1015
			if ($gateway['name'] == $showgw) {
1016
				$gws[] = $gateway['name'];
1017
				$link = "/system_gateways_edit.php?id={$i}";
1018
				break;
1019
			}
1020
			$i++;
1021
		}
1022
	}
1023
	$grouptiermap = [];
1024
	foreach(config_get_path('gateways/gateway_group') as $i => $gwgroup) {
1025
		if ($gwgroup['name'] == $showgw) {
1026
			$groupinfo = [];
1027
			foreach ($gwgroup['item'] as $member) {
1028
				$membersplit = explode("|", $member);
1029
				$groupinfo[] = [
1030
					'gw' => $membersplit[0],
1031
					'tier' => $membersplit[1],
1032
					'type' => $membersplit[2]
1033
				];
1034
				/* Store tier separately */
1035
				$grouptiermap[$membersplit[0]] = $membersplit[1];
1036
			}
1037
			/* Sort group info array by tier (number) and then by
1038
			 * name (natural) */
1039
			$gws = array_column($groupinfo, 'gw');
1040
			$tiers = array_column($groupinfo, 'tier');
1041
			array_multisort($tiers, SORT_NUMERIC,
1042
					$gws, SORT_NATURAL,
1043
					$groupinfo);
1044
			/* Re-slice member gateways which are now sorted */
1045
			$gws = array_column($groupinfo, 'gw');
1046
			$link = "system_gateway_groups_edit.php?id={$i}";
1047
			break;
1048
		}
1049
	}
1050

    
1051
	if (!empty($gws)) {
1052
		$content .= "<table>\n";
1053
		$content .= "<thead>\n";
1054
		$content .= "<tr>\n";
1055
		/* Only add Tier column if this is a group */
1056
		if (!empty($grouptiermap)) {
1057
			$content .= "<th>" . gettext("Tier") . "</th>";
1058
			$content .= "<th style='padding-left: 10px;'>";
1059
		} else {
1060
			$content .= "<th>";
1061
		}
1062
		$content .= gettext("Name") . "</th>";
1063
		$content .= "<th style='padding-left: 10px;'>" . gettext("Interface") . "</th>";
1064
		$content .= "<th style='padding-left: 10px;'>" . gettext("Gateway") . "</th></tr>\n";
1065
		$content .= "</thead>\n";
1066
		$content .= "<tbody>\n";
1067
		foreach ($gws as $gw) {
1068
			foreach ($gateways_status as $gwstatus) {
1069
				if ($gwstatus['name'] != $gw) {
1070
					continue;
1071
				}
1072
				/* Distinguish between online/offline in general */
1073
				if (stristr($gwstatus['status'], "online")) {
1074
					/* Use substatus to indicate warnings as needed */
1075
					if (in_array($gwstatus['substatus'], $bgdanger)) {
1076
						$bgcolor = "bg-danger";
1077
					} elseif (in_array($gwstatus['substatus'], $bgwarning)) {
1078
						$bgcolor = "bg-warning";
1079
					} elseif (in_array($gwstatus['substatus'], $bgsuccess)) {
1080
						$bgcolor = "bg-success";
1081
					}
1082
				} elseif (stristr($gwstatus['status'], "down")) {
1083
					/* Anything down is danger, no need to check substatus. */
1084
					$bgcolor = "bg-danger";
1085
				} else {
1086
					/* Unknown status */
1087
					$bgcolor = "bg-info";
1088
				}
1089
			}
1090
			$content .= "	<tr class='{$bgcolor}'>\n";
1091
			/* Only print Tier if this is a group */
1092
			if (!empty($grouptiermap)) {
1093
				$content .= "		<td>\n";
1094
				$content .= 			$grouptiermap[$gw];
1095
				$content .= "		</td>\n";
1096
			}
1097
			$content .= "		<td>\n";
1098
			$content .= 			$gw;
1099
			$content .= "		</td>\n";
1100
			$content .= "		<td style='padding-left: 10px;'>\n";
1101
			$content .= 			$a_gateways[$gw]['friendlyifdescr'];
1102
			$content .= "		</td>\n";
1103
			$content .= "		<td style='padding-left: 10px;'>\n";
1104
			$content .= 			$a_gateways[$gw]['gateway'];
1105
			$content .= "		</td>\n";
1106
			$content .= "	</tr>\n";
1107
		}
1108
		$content .= "</tbody>\n";
1109
		$content .= "</table>\n";
1110
	} else {
1111
		return;
1112
	}
1113

    
1114
	return "<a href=\"{$link}\" data-toggle=\"popover\" data-trigger=\"hover focus\" title=\"" . gettext('Gateway details') . "\" data-content=\"{$content}\" data-html=\"true\">";
1115
}
1116

    
1117
function rule_columns_with_alias($src, $srcport, $dst, $dstport, $target="", $targetport="") {
1118
	$columns = array();
1119
	foreach (config_get_path('aliases/alias', []) as $alias_id => $alias_name) {
1120
		if ($alias_name['name'] == $src) {
1121
			$columns['src'] = $alias_id;
1122
		}
1123
		if ($alias_name['name'] == $srcport) {
1124
			$columns['srcport'] = $alias_id;
1125
		}
1126
		if ($alias_name['name'] == $dst) {
1127
			$columns['dst'] = $alias_id;
1128
		}
1129
		if ($alias_name['name'] == $dstport) {
1130
			$columns['dstport'] = $alias_id;
1131
		}
1132
		if ($alias_name['name'] == $target) {
1133
			$columns['target'] = $alias_id;
1134
		}
1135
		if ($alias_name['name'] == $targetport) {
1136
			$columns['targetport'] = $alias_id;
1137
		}
1138
	}
1139

    
1140
	return $columns;
1141
}
1142

    
1143
function form_output_row($name, $label, $content) {
1144
var_dump($content);die;
1145
?>
1146
<div class="form-group">
1147
	<label for="<?=$name?>" class="col-sm-2 control-label"><?=gettext($label); ?></label>
1148
	<div class="col-sm-10">
1149
		<?=$content?>
1150
	</div>
1151
</div>
1152
<?php
1153
}
1154

    
1155
function set_flash_message($class, $msg) {
1156
	@phpsession_begin();
1157
	$_SESSION['flash_messages'][$class][] = $msg;
1158
	@phpsession_end(true);
1159
}
1160

    
1161
function get_flash_message() {
1162
	@phpsession_begin();
1163
	if (isset($_SESSION['flash_messages']) && !empty($_SESSION['flash_messages'])) {
1164
		foreach ($_SESSION['flash_messages'] as $class => $flash_message) {
1165
			print_info_box(implode("<br />", $flash_message), $class);
1166
		}
1167
		unset($_SESSION['flash_messages']);
1168
	}
1169
	@phpsession_end(true);
1170
}
1171

    
1172
/* Retrieve GET or POST Value/State
1173
 * Example Usage:
1174
 * $value = getGETPOSTsettingvalue('get/post parameter name', "");
1175
 * $value = getGETPOSTsettingvalue('get/post parameter name', null);
1176
 * $state = getGETPOSTsettingvalue('get/post parameter name', null);
1177
 * $state = getGETPOSTsettingvalue('get/post parameter name', false);
1178
 */
1179
function getGETPOSTsettingvalue($settingname, $default) {
1180
	$settingvalue = $default;
1181
	if ($_GET[$settingname]) {
1182
		$settingvalue = $_GET[$settingname];
1183
	}
1184
	if ($_POST[$settingname]) {
1185
		$settingvalue = $_POST[$settingname];
1186
	}
1187
	return $settingvalue;
1188
}
1189

    
1190
/* set timezone */
1191
$cfgtz = config_get_path('system/timezone');
1192
if ($cfgtz) {
1193
	$timezone = $cfgtz;
1194
} elseif (isset($g['default_timezone']) && !empty(g_get('default_timezone'))) {
1195
	$timezone = g_get('default_timezone');
1196
} else {
1197
	$timezone = "Etc/UTC";
1198
}
1199

    
1200
/* Remove files we do not want to see in a crash report */
1201
function cleanup_crash_file_list() {
1202
	$files = glob("/var/crash/*");
1203
	if (!is_array($files) || empty($files)) {
1204
		return array();
1205
	}
1206

    
1207
	$exclude_patterns = array(
1208
		'.*.last',
1209
		'bounds',
1210
		'minfree'
1211
	);
1212

    
1213
	foreach ($files as $idx => $fb) {
1214
		if (preg_match('/' . implode('|', $exclude_patterns) . '/', basename($fb)) == 1) {
1215
			unset($files[$idx]);
1216
		}
1217
	}
1218

    
1219
	return $files;
1220
}
1221

    
1222
function system_has_crash_data() {
1223
	/* Test if there are any crash data files present */
1224
	return count(cleanup_crash_file_list()) > 0;
1225
}
1226

    
1227
function system_has_php_errors() {
1228
	/* Check if the PHP error log is empty. Cast to int in case the file
1229
	 * does not exist and filesize() returns false. */
1230
	return (int) @filesize("/tmp/PHP_errors.log") > 0;
1231
}
1232

    
1233
date_default_timezone_set($timezone);
1234

    
1235
?>
(66-66/228)