Project

General

Profile

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

    
26
/* Include authentication routines */
27
/* THIS MUST BE ABOVE ALL OTHER CODE */
28
if (!$nocsrf) {
29
	function csrf_startup() {
30
		global $config;
31
		csrf_conf('rewrite-js', '/csrf/csrf-magic.js');
32
		$timeout_minutes = isset($config['system']['webgui']['session_timeout']) ? $config['system']['webgui']['session_timeout'] : 240;
33
		csrf_conf('expires', $timeout_minutes * 60);
34
	}
35
	require_once("csrf/csrf-magic.php");
36
}
37

    
38
/* make sure nothing is cached */
39
if (!$omit_nocacheheaders) {
40
	header("Expires: 0");
41
	header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
42
	header("Cache-Control: no-cache, no-store, must-revalidate");
43
	header("Pragma: no-cache");
44
}
45

    
46
header("X-Frame-Options: SAMEORIGIN");
47
require_once("authgui.inc");
48

    
49
/* parse the configuration and include all configuration functions */
50
require_once("functions.inc");
51

    
52
/* Include the autoloader for all the GUI display classes */
53
require_once("classes/autoload.inc.php");
54

    
55
/* used by progress bar */
56
$lastseen = "-1";
57

    
58
$navlevelsep = ": ";	/* navigation level separator string */
59
$mandfldhtml = "";		/* display this before mandatory input fields */
60
$mandfldhtmlspc = "";	/* same as above, but with spacing */
61

    
62
if (!function_exists('set_language')) {
63
	require_once("pfsense-utils.inc");
64
}
65

    
66
set_language();
67

    
68
/* Some ajax scripts still need access to GUI */
69
if (!$ignorefirmwarelock) {
70
	if (is_subsystem_dirty('firmwarelock')) {
71
		if (!$d_isfwfile) {
72
			header("Location: system_update.php");
73
			exit;
74
		} else {
75
			return;
76
		}
77
	}
78
}
79

    
80
/* Reserved table names to avoid collision */
81
$reserved_table_names = array(
82
	"bogons",
83
	"bogonsv6",
84
	"negate_networks",
85
	"snort2c",
86
	"sshlockout",
87
	"tonatsubnets",
88
	"virusprot",
89
	"vpn_networks",
90
	"webConfiguratorlockout"
91
);
92

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

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

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

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

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

    
136
$ldap_templates = array(
137

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

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

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

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

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

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

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

    
221
/* TCP flags */
222
$tcpflags = array("fin", "syn", "rst", "psh", "ack", "urg", "ece", "cwr");
223

    
224
$specialnets = array(
225
	"(self)" => gettext("This Firewall"),
226
	"pppoe" => gettext("PPPoE clients"),
227
	"l2tp" => gettext("L2TP clients"));
228

    
229
$spiflist = get_configured_interface_with_descr(false, true);
230
foreach ($spiflist as $ifgui => $ifdesc) {
231
	$specialnets[$ifgui] = $ifdesc . " net";
232
	$specialnets[$ifgui . 'ip'] = $ifdesc . " address";
233
}
234

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

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

    
247
function do_input_validation($postdata, $reqdfields, $reqdfieldsn, &$input_errors) {
248

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

    
256
	for ($i = 0; $i < count($reqdfields); $i++) {
257
		if ($_POST[$reqdfields[$i]] == "" && $_REQUEST[$reqdfields[$i]] == "") {
258
			$input_errors[] = sprintf(gettext("The field %s is required."), $reqdfieldsn[$i]);
259
		}
260
	}
261
}
262

    
263
function print_input_errors($input_errors) {
264
	echo '<div class="alert alert-danger input-errors">';
265
	echo '<p>' . gettext('The following input errors were detected:') . '</p>';
266
	echo '<ul>';
267

    
268
	foreach ($input_errors as $ierr) {
269
		echo '<li>' . htmlspecialchars($ierr) . '</li>';
270
	}
271

    
272
	echo '</ul>';
273
	echo '</div>';
274
}
275

    
276
function verify_gzip_file($fname) {
277
	$returnvar = mwexec("/usr/bin/gzip -t " . escapeshellarg($fname));
278
	if ($returnvar != 0) {
279
		return 0;
280
	} else {
281
		return 1;
282
	}
283
}
284

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

    
295
	if (strpos($class, "alert-") !== 0) {
296
		$class = 'alert-' . $class;
297
	}
298

    
299
	$msg = '<div class="pull-left">' . $msg . '</div>';
300

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

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

    
313
		if ($_POST['if']) {
314
			$msg .= "<input type=\"hidden\" name=\"if\" value=\"" . htmlspecialchars($_POST['if']) . "\" />";
315
		}
316

    
317
		$msg .= '</form>';
318
	}
319

    
320
	return '<div class="alert ' . $class . ' clearfix" role="alert">' . $msg . '</div>';
321
}
322

    
323
// Format and print an info box. See sprint_info_box() for details.
324
function print_info_box($msg, $class="alert-warning", $btnname = "close", $btntext = "", $btnicon = "", $btnclass = "default") {
325
	echo sprint_info_box($msg, $class, $btnname, $btntext, $btnicon, $btnclass);
326
}
327

    
328
function print_apply_box($msg) {
329
	print_info_box($msg, "warning", "apply", gettext("Apply Changes"), 'fa-check', 'success');
330
}
331

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

    
347
	if (strlen($extra_text) > 0) {
348
		$result_msg .= " " . $extra_text;
349
	}
350
	print_info_box($result_msg, $severity);
351
}
352

    
353
/*
354
 * Print Bootstrap callout
355
 *
356
 * @param string $msg     message to display
357
 * @param string $class   contextual class, defaults to info (default | danger | warning | info)
358
 * @param string $heading optional callout heading
359
 */
360
function print_callout($msg, $class = 'info', $heading = '') {
361

    
362
	if ('' == $msg) {
363
		return;
364
	}
365
	$class = strtolower($class);
366
	$callout = '';
367

    
368
	if ($class != 'default' && $class != 'danger' && $class != 'warning' && $class != 'info') {
369
		$class = 'info';
370
	}
371
	$callout .= '<div class="bs-callout bs-callout-' . $class . '">';
372

    
373
	if ('' != $heading) {
374
		$callout .= '<h4>' . $heading . '</h4>';
375
	}
376
	$callout .= $msg . '</div>';
377
	echo $callout;
378
}
379

    
380
function get_std_save_message($retval) {
381
	$filter_related = false;
382
	$filter_pages = array("nat", "filter");
383
	if ($retval === 0) {
384
		// 0 is success
385
		$to_return = gettext("The changes have been applied successfully.");
386
	} else {
387
		// non-zero means there was some problem
388
		$to_return = gettext("There was a problem applying the changes. See the <a href=\"status_logs.php\">System Logs</a>.");
389
	}
390
	foreach ($filter_pages as $fp) {
391
		if (stristr($_SERVER['SCRIPT_FILENAME'], $fp)) {
392
			$filter_related = true;
393
		}
394
	}
395
	if ($filter_related) {
396
		$to_return .= "<br />" . gettext("<a href=\"status_filter_reload.php\">Monitor</a> the filter reload progress.");
397
	}
398
	return $to_return;
399
}
400

    
401
function pprint_address($adr) {
402
	global $specialnets;
403

    
404
	if (isset($adr['any'])) {
405
		$padr = "*";
406
	} else if ($adr['network']) {
407
		$padr = $specialnets[$adr['network']];
408
	} else {
409
		$padr = $adr['address'];
410
	}
411

    
412
	if (isset($adr['not'])) {
413
		$padr = "! " . $padr;
414
	}
415

    
416
	return $padr;
417
}
418

    
419
function pprint_port($port) {
420
	global $wkports;
421

    
422
	$pport = "";
423

    
424
	if (!$port) {
425
		return "*";
426
	} else {
427
		$srcport = explode("-", $port);
428
		if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
429
			$pport = $srcport[0];
430
			if ($wkports[$srcport[0]]) {
431
				$pport .= " (" . $wkports[$srcport[0]] . ")";
432
			}
433
		} else {
434
			$pport .= $srcport[0] . " - " . $srcport[1];
435
		}
436
	}
437

    
438
	return $pport;
439
}
440

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

    
516
	return $item_set;
517
}
518

    
519
function gentitle($title) {
520
	global $navlevelsep;
521
	if (!is_array($title)) {
522
		return $title;
523
	} else {
524
		return join($navlevelsep, $title);
525
	}
526
}
527

    
528
function genhtmltitle($title, $links=true) {
529

    
530
	$num_crumbs = count($title);
531

    
532
	// If the array contains only one element, there are no breadcrumbs, so don't
533
	// add anything else
534
	if ($num_crumbs > 1) {
535
		$bc = '<ol class="breadcrumb">';
536

    
537
		if (!is_array($links)) {
538
			$gen_default = ($links === true);
539
			$links = array_fill(0, $num_crumbs, '');
540
			// If no links passed, then default to a link to self on the last entry.
541
			if ($gen_default) {
542
				$links[$num_crumbs-1] = '@self';
543
			}
544
		}
545

    
546
		foreach ($title as $idx => $el) {
547
			$href = $links[$idx];
548
			if (strlen($href) > 0) {
549
				// For convenience, if the caller specifies '@self' then make a link
550
				// to the current page, including any query string.
551
				if ($href == '@self') {
552
					$href = $_SERVER['REQUEST_URI'];
553
				}
554
				if (substr($href, 0, 1) != '/') {
555
					$href = '/' . $href;
556
				}
557
				$bc .= '<li><a href="' . htmlentities($href) . '">' . $el . '</a></li>';
558
			} else {
559
				$bc .= '<li>' . $el . '</li>';
560
			}
561
		}
562

    
563
		$bc .= '</ol>';
564
	} else {
565
		$bc = "";
566
	}
567

    
568
	return $bc;
569
}
570

    
571
/* update the changedesc and changecount(er) variables */
572
function update_changedesc($update) {
573
	global $changedesc;
574
	global $changecount;
575

    
576
	$changedesc .= " {$update}";
577
	$changecount++;
578
}
579

    
580
// This version of dump_clog() does not output <td></td> or any other table elements.
581
function dump_clog_no_table($logfile, $tail, $withorig = true, $grepfor = "", $grepinvert = "") {
582
	global $g, $config;
583
	$sor = isset($config['syslog']['reverse']) ? "-r" : "";
584
	$specific_log = basename($logfile, '.log') . '_settings';
585
	if ($config['syslog'][$specific_log]['cronorder'] == 'forward') $sor = "";
586
	if ($config['syslog'][$specific_log]['cronorder'] == 'reverse') $sor = "-r";
587
	$logarr = array();
588
	$grepline = "  ";
589
	if (is_array($grepfor)) {
590
		$invert = '';
591
		if ((strpos($grepfor[0], '!') === 0)) {
592
			$grepfor[0] = substr($grepfor[0], 1);
593
			$invert = '-v';
594
		}
595
		$grepline .= " | /usr/bin/egrep {$invert} " . escapeshellarg(implode("|", $grepfor));
596
	}
597
	if (is_array($grepinvert)) {
598
		$grepline .= " | /usr/bin/egrep -v " . escapeshellarg(implode("|", $grepinvert));
599
	}
600
	if (is_dir($logfile)) {
601
		$logarr = array(sprintf(gettext("File %s is a directory."), $logfile));
602
	} elseif (file_exists($logfile) && filesize($logfile) == 0) {
603
		$logarr = array(gettext("Log file started."));
604
	} else {
605
		if ($config['system']['disablesyslogclog']) {
606
			exec("cat " . escapeshellarg($logfile) . "{$grepline} | /usr/bin/tail {$sor} -n " . escapeshellarg($tail), $logarr);
607
		} else {
608
			exec("/usr/local/sbin/clog " . escapeshellarg($logfile) . "{$grepline}| grep -v \"CLOG\" | grep -v \"\033\" | /usr/bin/tail {$sor} -n " . escapeshellarg($tail), $logarr);
609
		}
610
	}
611
	echo "\n";
612

    
613
	$rows = 0;
614
	foreach ($logarr as $logent) {
615
		$rows++;
616
		$logent = preg_split("/\s+/", $logent, 6);
617

    
618
		if ($withorig) {
619
				$entry_date_time = htmlspecialchars(join(" ", array_slice($logent, 0, 3)));
620
				$entry_text = ($logent[3] ==  $config['system']['hostname']) ? "" : $logent[3] . " ";
621
				$entry_text .= htmlspecialchars($logent[4] . " " . $logent[5]);
622
				echo "{$entry_date_time}";
623
				echo " " . "{$entry_text}"	. "\n";
624
		} else {
625
				echo htmlspecialchars($logent[5]) . "\n";
626
		}
627

    
628
	}
629
	return($rows);
630
}
631

    
632
function dump_clog($logfile, $tail, $withorig = true, $grepfor = "", $grepinvert = "") {
633
	global $g, $config;
634
	$sor = isset($config['syslog']['reverse']) ? "-r" : "";
635
	$specific_log = basename($logfile, '.log') . '_settings';
636
	if ($config['syslog'][$specific_log]['cronorder'] == 'forward') $sor = "";
637
	if ($config['syslog'][$specific_log]['cronorder'] == 'reverse') $sor = "-r";
638
	$logarr = array();
639
	$grepline = "  ";
640
	if (is_array($grepfor)) {
641
		$invert = '';
642
		if ((strpos($grepfor[0], '!') === 0)) {
643
			$grepfor[0] = substr($grepfor[0], 1);
644
			$invert = '-v';
645
		}
646
		$grepline .= " | /usr/bin/egrep {$invert} " . escapeshellarg(implode("|", $grepfor));
647
	}
648
	if (is_array($grepinvert)) {
649
		$grepline .= " | /usr/bin/egrep -v " . escapeshellarg(implode("|", $grepinvert));
650
	}
651
	if (is_dir($logfile)) {
652
		$logarr = array(sprintf(gettext("File %s is a directory."), $logfile));
653
	} elseif (file_exists($logfile) && filesize($logfile) == 0) {
654
		$logarr = array(gettext("Log file started."));
655
	} else {
656
		if ($config['system']['disablesyslogclog']) {
657
			exec("cat " . escapeshellarg($logfile) . "{$grepline} | /usr/bin/tail {$sor} -n " . escapeshellarg($tail), $logarr);
658
		} else {
659
			exec("/usr/local/sbin/clog " . escapeshellarg($logfile) . "{$grepline}| grep -v \"CLOG\" | grep -v \"\033\" | /usr/bin/tail {$sor} -n " . escapeshellarg($tail), $logarr);
660
		}
661
	}
662

    
663
	$rows = 0;
664
	foreach ($logarr as $logent) {
665
		$rows++;
666
		$logent = preg_split("/\s+/", $logent, 6);
667
		echo "<tr>\n";
668
		if ($withorig) {
669
			$entry_date_time = htmlspecialchars(join(" ", array_slice($logent, 0, 3)));
670
			$entry_text = ($logent[3] == $config['system']['hostname']) ? "" : $logent[3] . " ";
671
			$entry_text .= htmlspecialchars($logent[4] . " " . $logent[5]);
672
			echo "<td class=\"text-nowrap\">{$entry_date_time}</td>\n";
673
			echo "<td style=\"word-wrap:break-word; word-break:break-all; white-space:normal\">{$entry_text}</td>\n";
674
		} else {
675
				echo "<td>" . htmlspecialchars($logent[5]) . "</td>\n";
676
		}
677
		echo "</tr>\n";
678
	}
679
	return($rows);
680
}
681

    
682
function return_clog($logfile, $tail, $withorig = true, $grepfor = "", $grepinvert = "", $grepreverse = false) {
683
	global $g, $config;
684
	$sor = (isset($config['syslog']['reverse']) || $grepreverse) ? "-r" : "";
685
	$specific_log = basename($logfile, '.log') . '_settings';
686
	if (($config['syslog'][$specific_log]['cronorder'] == 'forward') && !$grepreverse) $sor = "";
687
	if (($config['syslog'][$specific_log]['cronorder'] == 'reverse') ||  $grepreverse) $sor = "-r";
688
	$logarr = array();
689
	$grepline = "  ";
690
	if (is_array($grepfor)) {
691
		$grepline .= " | /usr/bin/egrep " . escapeshellarg(implode("|", $grepfor));
692
	}
693
	if (is_array($grepinvert)) {
694
		$grepline .= " | /usr/bin/egrep -v " . escapeshellarg(implode("|", $grepinvert));
695
	}
696
	if ($config['system']['disablesyslogclog']) {
697
		exec("cat " . escapeshellarg($logfile) . "{$grepline} | /usr/bin/tail {$sor} -n " . escapeshellarg($tail), $logarr);
698
	} else {
699
		exec("/usr/local/sbin/clog " . escapeshellarg($logfile) . "{$grepline}| grep -v \"CLOG\" | grep -v \"\033\" | /usr/bin/tail {$sor} -n " . escapeshellarg($tail), $logarr);
700
	}
701
	return($logarr);
702
}
703

    
704
/* Check if variable has changed, update and log if it has
705
 * returns true if var changed
706
 * varname = variable name in plain text
707
 * orig = original value
708
 * new = new value
709
 */
710
function update_if_changed($varname, & $orig, $new) {
711
	if (is_array($orig) && is_array($new)) {
712
		$a_diff = array_diff($orig, $new);
713
		foreach ($a_diff as $diff) {
714
			update_changedesc("removed {$varname}: \"{$diff}\"");
715
		}
716
		$a_diff = array_diff($new, $orig);
717
		foreach ($a_diff as $diff) {
718
			update_changedesc("added {$varname}: \"{$diff}\"");
719
		}
720
		$orig = $new;
721
		return true;
722

    
723
	} else {
724
		if ($orig != $new) {
725
			update_changedesc("{$varname}: \"{$orig}\" -> \"{$new}\"");
726
			$orig = $new;
727
			return true;
728
		}
729
	}
730
	return false;
731
}
732

    
733
function address_to_pconfig($adr, &$padr, &$pmask, &$pnot, &$pbeginport, &$pendport) {
734
	if (isset($adr['any'])) {
735
		$padr = "any";
736
	} else if ($adr['network']) {
737
		$padr = $adr['network'];
738
	} else if ($adr['address']) {
739
		list($padr, $pmask) = explode("/", $adr['address']);
740
		if (!$pmask) {
741
			if (is_ipaddrv6($padr)) {
742
				$pmask = 128;
743
			} else {
744
				$pmask = 32;
745
			}
746
		}
747
	}
748

    
749
	if (isset($adr['not'])) {
750
		$pnot = 1;
751
	} else {
752
		$pnot = 0;
753
	}
754

    
755
	if ($adr['port']) {
756
		list($pbeginport, $pendport) = explode("-", $adr['port']);
757
		if (!$pendport) {
758
			$pendport = $pbeginport;
759
		}
760
	} else if (!is_alias($pbeginport) && !is_alias($pendport)) {
761
		$pbeginport = "any";
762
		$pendport = "any";
763
	}
764
}
765

    
766
function pconfig_to_address(&$adr, $padr, $pmask, $pnot = false, $pbeginport = 0, $pendport = 0) {
767
	$adr = array();
768

    
769
	if ($padr == "any") {
770
		$adr['any'] = true;
771
	} else if (is_specialnet($padr)) {
772
		$adr['network'] = $padr;
773
	} else {
774
		$adr['address'] = $padr;
775
		if (is_ipaddrv6($padr)) {
776
			if ($pmask != 128) {
777
				$adr['address'] .= "/" . $pmask;
778
			}
779
		} else {
780
			if ($pmask != 32) {
781
				$adr['address'] .= "/" . $pmask;
782
			}
783
		}
784
	}
785

    
786
	if ($pnot) {
787
		$adr['not'] = true;
788
	} else {
789
		unset($adr['not']);
790
	}
791

    
792
	if (($pbeginport != 0) && ($pbeginport != "any")) {
793
		if ($pbeginport != $pendport) {
794
			$adr['port'] = $pbeginport . "-" . $pendport;
795
		} else {
796
			$adr['port'] = $pbeginport;
797
		}
798
	}
799

    
800
	if (is_alias($pbeginport)) {
801
		$adr['port'] = $pbeginport;
802
	}
803
}
804

    
805
function is_specialnet($net) {
806
	global $specialsrcdst;
807

    
808
	if (!$net) {
809
		return false;
810
	}
811
	if (in_array($net, $specialsrcdst)) {
812
		return true;
813
	} else {
814
		return false;
815
	}
816
}
817

    
818
//function to create widget tabs when called
819
function display_widget_tabs(& $tab_array) {
820
	echo "<div id=\"tabs\">";
821
	$tabscounter = 0;
822
	foreach ($tab_array as $ta) {
823
		$dashpos = strpos($ta[2], '-');
824
		$tabname = $ta[2] . "-tab";
825
		$tabclass = substr($ta[2], 0, $dashpos);
826
		$tabclass = $tabclass . "-class";
827
		if ($ta[1] == true) {
828
			$tabActive = "table-cell";
829
			$tabNonActive = "none";
830
		} else {
831
			$tabActive = "none";
832
			$tabNonActive = "table-cell";
833
		}
834
		echo "<div id=\"{$ta[2]}-active\" class=\"{$tabclass}-tabactive\" style=\"display:{$tabActive}; background-color:#EEEEEE; color:black;\">";
835
		echo "<b>&nbsp;&nbsp;&nbsp;{$ta[0]}";
836
		echo "&nbsp;&nbsp;&nbsp;</b>";
837
		echo "</div>";
838

    
839
		echo "<div id=\"{$ta[2]}-deactive\" class=\"{$tabclass}-tabdeactive\" style=\"display:{$tabNonActive}; background-color:#777777; color:white; cursor: pointer;\" onclick=\"return changeTabDIV('{$ta[2]}')\">";
840
		echo "<b>&nbsp;&nbsp;&nbsp;{$ta[0]}";
841
		echo "&nbsp;&nbsp;&nbsp;</b>";
842
		echo "</div>";
843
	}
844
	echo "</div>";
845
}
846

    
847

    
848
// Return inline javascript file or CSS to minimize
849
// request count going back to server.
850
function outputJavaScriptFileInline($javascript) {
851
	if (file_exists($javascript)) {
852
		echo "\n<script type=\"text/javascript\">\n";
853
		include_once($javascript);
854
		echo "\n</script>\n";
855
	} else {
856
		echo "\n\n<!-- Could not locate file:  {$javascript} -->\n\n";
857
	}
858
}
859

    
860

    
861

    
862
function outputCSSPrintFileInline($css) {
863
	if (file_exists($css)) {
864
		echo "\n<style media=\"print\" type=\"text/css\">\n";
865
		include_once($css);
866
		echo "\n</style>\n";
867
	} else {
868
		echo "\n\n<!-- Could not locate file:  {$css} -->\n\n";
869
	}
870
}
871

    
872

    
873
function outputCSSFileInline($css) {
874
	if (file_exists($css)) {
875
		echo "\n<style type=\"text/css\">\n";
876
		include_once($css);
877
		echo "\n</style>\n";
878
	} else {
879
		echo "\n\n<!-- Could not locate file:  {$css} -->\n\n";
880
	}
881
}
882

    
883
$rfc2616 = array(
884
	100 => "100 Continue",
885
	101 => "101 Switching Protocols",
886
	200 => "200 OK",
887
	201 => "201 Created",
888
	202 => "202 Accepted",
889
	203 => "203 Non-Authoritative Information",
890
	204 => "204 No Content",
891
	205 => "205 Reset Content",
892
	206 => "206 Partial Content",
893
	300 => "300 Multiple Choices",
894
	301 => "301 Moved Permanently",
895
	302 => "302 Found",
896
	303 => "303 See Other",
897
	304 => "304 Not Modified",
898
	305 => "305 Use Proxy",
899
	306 => "306 (Unused)",
900
	307 => "307 Temporary Redirect",
901
	400 => "400 Bad Request",
902
	401 => "401 Unauthorized",
903
	402 => "402 Payment Required",
904
	403 => "403 Forbidden",
905
	404 => "404 Not Found",
906
	405 => "405 Method Not Allowed",
907
	406 => "406 Not Acceptable",
908
	407 => "407 Proxy Authentication Required",
909
	408 => "408 Request Timeout",
910
	409 => "409 Conflict",
911
	410 => "410 Gone",
912
	411 => "411 Length Required",
913
	412 => "412 Precondition Failed",
914
	413 => "413 Request Entity Too Large",
915
	414 => "414 Request-URI Too Long",
916
	415 => "415 Unsupported Media Type",
917
	416 => "416 Requested Range Not Satisfiable",
918
	417 => "417 Expectation Failed",
919
	500 => "500 Internal Server Error",
920
	501 => "501 Not Implemented",
921
	502 => "502 Bad Gateway",
922
	503 => "503 Service Unavailable",
923
	504 => "504 Gateway Timeout",
924
	505 => "505 HTTP Version Not Supported"
925
);
926

    
927
function is_rfc2616_code($code) {
928
	global $rfc2616;
929
	if (isset($rfc2616[$code])) {
930
		return true;
931
	} else {
932
		return false;
933
	}
934
}
935

    
936
function print_rfc2616_select($tag, $current) {
937
	global $rfc2616;
938

    
939
	/* Default to 200 OK if not set */
940
	if ($current == "") {
941
		$current = 200;
942
	}
943

    
944
	echo "<select id=\"{$tag}\" name=\"{$tag}\">\n";
945
	foreach ($rfc2616 as $code => $message) {
946
		if ($code == $current) {
947
			$sel = " selected";
948
		} else {
949
			$sel = "";
950
		}
951
		echo "<option value=\"{$code}\"{$sel}>{$message}</option>\n";
952
	}
953
	echo "</select>\n";
954
}
955

    
956
// Useful debugging function, much cleaner than print_r
957
function echo_array($array, $return_me = false) {
958
	if (is_array($array) == false) {
959
		$return = "The provided variable is not an array.";
960
	} else {
961
		foreach ($array as $name=>$value) {
962
			if (is_array($value)) {
963
				$return .= "";
964
				$return .= "['<b>$name</b>'] {<div style=\"margin-left:10px;\">\n";
965
				$return .= echo_array($value, true);
966
				$return .= "</div>}";
967
				$return .= "\n\n";
968
			} else {
969
				if (is_string($value)) {
970
					$value = "\"$value\"";
971
				}
972
				$return .= "['<b>$name</b>'] = $value\n\n";
973
			}
974
		}
975
	}
976
	if ($return_me == true) {
977
		return $return;
978
	} else {
979
		echo "<pre>".$return."</pre>";
980
	}
981
}
982

    
983
/****f* pfsense-utils/display_top_tabs
984
 * NAME
985
 *	 display_top_tabs - display tabs with rounded edges
986
 * INPUTS
987
 *	 $text	  - array of tabs
988
 * RESULT
989
 *	 null
990
 ******/
991
function display_top_tabs(& $tab_array, $no_drop_down = false, $type = 'pills') {
992
	global $config;
993
	global $g;
994
	global $tab_array_indent;
995
	global $tab_array_space;
996
	global $tab_array_char_limit;
997

    
998
	/*	does the user have access to this tab?
999
	 *	master user has access to everything.
1000
	 *	if the user does not have access, simply
1001
	 *	unset the tab item.
1002
	 */
1003

    
1004
	/* empty string code */
1005
	if ($tab_array_indent == '') {
1006
		$tab_array_indent = 0;
1007
	}
1008

    
1009
	if ($tab_array_space == '') {
1010
		$tab_array_space = 1;
1011
	}
1012

    
1013
	if ($tab_array_char_limit == '') {
1014
		$tab_array_char_limit = 92;
1015
	}
1016

    
1017
	foreach ($tab_array as $tab_id => $ta) {
1018
		if (!isAllowedPage($ta[2])) {
1019
			unset ($tab_array[$tab_id]);
1020
		}
1021
	}
1022

    
1023
	$tab_active_bg	 = "#EEEEEE";
1024
	$tab_inactive_bg = "#777777";
1025
	$nifty_tabs_corners = "#FFF";
1026
	$font_color = "white";
1027

    
1028
	$tabcharcount = 0;
1029
	foreach ($tab_array as $ta) {
1030
		$tabcharcount = $tabcharcount + strlen($ta[0]);
1031
	}
1032

    
1033
	if ($no_drop_down == true) {
1034
		$tabcharcount = 0;
1035
		unset($tab_array_char_limit);
1036
	}
1037

    
1038
	// If the character count of the tab names is > 670
1039
	// then show a select item dropdown menubox.
1040
	if ($tabcharcount > $tab_array_char_limit) {
1041
		echo gettext("Currently viewing: ");
1042
		echo "<select name=\"TabSelect\" onchange=\"tabs_will_go(this)\">\n";
1043

    
1044
		foreach ($tab_array as $ta) {
1045
			if ($ta[1] == "true") {
1046
				$selected = " selected";
1047
			} else {
1048
				$selected = "";
1049
			}
1050
			// Onclick in option will not work in some browser
1051
			// echo "<option onclick=\"document.location='{$ta[2]}';\"{$selected}>{$ta['0']}</option>\n";
1052
			echo "<option value=\"{$ta[2]}\"{$selected}>{$ta['0']}</option>\n";
1053
		}
1054

    
1055
		echo "</select>\n<p>&nbsp;</p>";
1056
		echo "<script type=\"text/javascript\">";
1057
		echo "\n//<![CDATA[\n";
1058
		echo " function tabs_will_go(obj){ document.location = obj.value; }\n";
1059
		echo "//]]>\n";
1060
		echo "</script>";
1061
	} else {
1062
		echo '<ul class="nav nav-' . $type . '">';
1063

    
1064
		foreach ($tab_array as $ta) {
1065
			echo '<li role="presentation"';
1066
			if ($ta[1]) {
1067
				echo ' class="active"';
1068
			}
1069

    
1070
			echo '><a href="' . $ta[2] . '">' . $ta[0] . '</a></li>';
1071
		}
1072

    
1073
		echo '</ul>';
1074
	}
1075
}
1076

    
1077
function add_package_tabs($tabgroup, &$tab_array) {
1078
	global $config, $g;
1079

    
1080
	if (!isset($config['installedpackages']['package'])) {
1081
		return;
1082
	}
1083

    
1084
	foreach ($config['installedpackages']['package'] as $pkg) {
1085
		$pkg_config = read_package_configurationfile($pkg['name']);
1086

    
1087
		if (!isset($pkg_config['tabs']['tab'])) {
1088
			continue;
1089
		}
1090

    
1091
		foreach ($pkg_config['tabs']['tab'] as $tab) {
1092
			$tab_entry = array();
1093
			if ($tab['name']) {
1094
				$tab_entry[] = $tab['name'];
1095
				$tab_entry[] = false;
1096
				$tab_entry[] = $tab['url'];
1097
				$tab_array[] = $tab_entry;
1098
			}
1099
		}
1100
	}
1101
}
1102

    
1103
function alias_info_popup($alias_id) {
1104
	global $config;
1105

    
1106
	if (!is_array($config['aliases']['alias'][$alias_id])) {
1107
		return;
1108
	}
1109

    
1110
	$maxlength = 60;
1111
	$alias = $config['aliases']['alias'][$alias_id];
1112
	$content = "";
1113

    
1114
	if ($alias['url']) {
1115
		// TODO: Change it when pf supports tables with ports
1116
		if ($alias['type'] == "urltable") {
1117
			exec("/sbin/pfctl -t {$alias['name']} -T show | wc -l", $total_entries);
1118
			$counter=preg_replace("/\D/", "", $total_entries[0]);
1119
			exec("/sbin/pfctl -t {$alias['name']} -T show | head -10002", $alias_addresses);
1120
		} else {
1121
			$urlfn = alias_expand_urltable($alias['name']);
1122
			$alias_addresses = explode("\n", file_get_contents($urlfn));
1123
			$counter = count($alias_addresses);
1124
		}
1125

    
1126
		$content .= '<h5>'. $alias['url'] .'</h5><ul><li>'. implode('</li><li>', $alias_addresses) .'</li></ul>';
1127
		if ($counter > 10002) {
1128
			$content .= '<i>'. gettext("listing only first 10k items") .'</i>';
1129
		}
1130
	} else {
1131
		$alias_addresses = explode (" ", $alias['address']);
1132
		$alias_details = explode ("||", $alias['detail']);
1133
		$idx = 0;
1134

    
1135
		$content .= "<table>\n";
1136
		$content .= "<thead>\n";
1137
		$content .= "<tr>\n";
1138
		$content .= "<th>" . gettext("Value") . "</th><th  style='padding-left: 10px;'>" . gettext("Description") . "</th></tr>\n";
1139
		$content .= "</thead>\n";
1140
		$content .= "<tbody>\n";
1141

    
1142
		foreach ($alias_addresses as $ap) {
1143
			$content .= "	<tr>\n";
1144
			$content .= "		<td>\n";
1145
			$content .= 			$ap;
1146
			$content .=	"		</td>\n";
1147
			$content .= "		<td style='padding-left: 10px;'>\n";
1148
			$content .= 			htmlspecialchars($alias_details[$idx]);
1149
			$content .=	"		</td>\n";
1150
			$content .= "	</tr>\n";
1151
			$idx++;
1152
		}
1153

    
1154
		$content .= "</tbody>\n";
1155
		$content .= "<table>\n";
1156
	}
1157

    
1158
	if (strlen($alias['descr']) >= $maxlength) {
1159
		$alias['descr'] = substr($alias['descr'], 0, $maxlength) . '&hellip;';
1160
	}
1161

    
1162
	return $content;
1163
}
1164

    
1165
function rule_columns_with_alias($src, $srcport, $dst, $dstport, $target="", $targetport="") {
1166
	global $config;
1167

    
1168
	if ($config['aliases']['alias'] == "" || !is_array($config['aliases']['alias'])) {
1169
		return;
1170
	}
1171

    
1172
	$columns = array();
1173
	foreach ($config['aliases']['alias'] as $alias_id => $alias_name) {
1174
		if ($alias_name['name'] == $src) {
1175
			$columns['src'] = $alias_id;
1176
		}
1177
		if ($alias_name['name'] == $srcport) {
1178
			$columns['srcport'] = $alias_id;
1179
		}
1180
		if ($alias_name['name'] == $dst) {
1181
			$columns['dst'] = $alias_id;
1182
		}
1183
		if ($alias_name['name'] == $dstport) {
1184
			$columns['dstport'] = $alias_id;
1185
		}
1186
		if ($alias_name['name'] == $target) {
1187
			$columns['target'] = $alias_id;
1188
		}
1189
		if ($alias_name['name'] == $targetport) {
1190
			$columns['targetport'] = $alias_id;
1191
		}
1192
	}
1193

    
1194
	return $columns;
1195
}
1196

    
1197
function form_output_row($name, $label, $content) {
1198
var_dump($content);die;
1199
?>
1200
<div class="form-group">
1201
	<label for="<?=$name?>" class="col-sm-2 control-label"><?=gettext($label); ?></label>
1202
	<div class="col-sm-10">
1203
		<?=$content?>
1204
	</div>
1205
</div>
1206
<?php
1207
}
1208

    
1209
function set_flash_message($class, $msg) {
1210
	@session_start();
1211
	$_SESSION['flash_messages'][$class][] = $msg;
1212
}
1213

    
1214
function get_flash_message() {
1215
	@session_start();
1216
	if (isset($_SESSION['flash_messages']) && !empty($_SESSION['flash_messages'])) {
1217
		foreach ($_SESSION['flash_messages'] as $class => $flash_message) {
1218
			print_info_box(implode("<br />", $flash_message), $class);
1219
		}
1220
		unset($_SESSION['flash_messages']);
1221
	}
1222
}
1223

    
1224
/* Retrieve GET or POST Value/State
1225
 * Eample Usage:
1226
 * $value = getGETPOSTsettingvalue('get/post parameter name', "");
1227
 * $value = getGETPOSTsettingvalue('get/post parameter name', null);
1228
 * $state = getGETPOSTsettingvalue('get/post parameter name', null);
1229
 * $state = getGETPOSTsettingvalue('get/post parameter name', false);
1230
 */
1231
function getGETPOSTsettingvalue($settingname, $default) {
1232
	$settingvalue = $default;
1233
	if ($_GET[$settingname]) {
1234
		$settingvalue = $_GET[$settingname];
1235
	}
1236
	if ($_POST[$settingname]) {
1237
		$settingvalue = $_POST[$settingname];
1238
	}
1239
	return $settingvalue;
1240
}
1241

    
1242
/* set timezone */
1243
if (isset($config['system']['timezone']) &&
1244
    !empty($config['system']['timezone'])) {
1245
	$timezone = $config['system']['timezone'];
1246
} elseif (isset($g['default_timezone']) && !empty($g['default_timezone'])) {
1247
	$timezone = $g['default_timezone'];
1248
} else {
1249
	$timezone = "Etc/UTC";
1250
}
1251

    
1252
date_default_timezone_set($timezone);
1253

    
1254
?>
(62-62/225)