Project

General

Profile

Download (33.5 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("firewall_aliases", "firewall_nat", "firewall_rules", "status_logs_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 = sprintf(gettext('There was a problem applying the changes. See the %1$sSystem Logs%2$s.'), '<a href=\"status_logs.php\">', '</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 .= " " . gettext("The firewall rules are now reloading in the background.") . "<br />" .
397
		    sprintf(gettext('%1$sMonitor%2$s the filter reload progress.'), "<a href='status_filter_reload.php'>", "</a>");
398
	}
399
	return $to_return;
400
}
401

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

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

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

    
417
	return $padr;
418
}
419

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

    
423
	$pport = "";
424

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

    
439
	return $pport;
440
}
441

    
442
function insert_word_breaks_in_domain_name($domain_name) {
443
	return str_replace('.', '<wbr>.', $domain_name);
444
}
445

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

    
521
	return $item_set;
522
}
523

    
524
function gentitle($title) {
525
	global $navlevelsep;
526
	if (!is_array($title)) {
527
		return $title;
528
	} else {
529
		return join($navlevelsep, $title);
530
	}
531
}
532

    
533
function genhtmltitle($title, $links=true) {
534

    
535
	$num_crumbs = count($title);
536

    
537
	// If the array contains only one element, there are no breadcrumbs, so don't
538
	// add anything else
539
	if ($num_crumbs > 1) {
540
		$bc = '<ol class="breadcrumb">';
541

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

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

    
568
		$bc .= '</ol>';
569
	} else {
570
		$bc = "";
571
	}
572

    
573
	return $bc;
574
}
575

    
576
/* update the changedesc and changecount(er) variables */
577
function update_changedesc($update) {
578
	global $changedesc;
579
	global $changecount;
580

    
581
	$changedesc .= " {$update}";
582
	$changecount++;
583
}
584

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

    
618
	$rows = 0;
619
	foreach ($logarr as $logent) {
620
		$rows++;
621
		$logent = preg_split("/\s+/", $logent, 6);
622

    
623
		if ($withorig) {
624
				$entry_date_time = htmlspecialchars(join(" ", array_slice($logent, 0, 3)));
625
				$entry_text = ($logent[3] ==  $config['system']['hostname']) ? "" : $logent[3] . " ";
626
				$entry_text .= htmlspecialchars($logent[4] . " " . $logent[5]);
627
				echo "{$entry_date_time}";
628
				echo " " . "{$entry_text}"	. "\n";
629
		} else {
630
				echo htmlspecialchars($logent[5]) . "\n";
631
		}
632

    
633
	}
634
	return($rows);
635
}
636

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

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

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

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

    
728
	} else {
729
		if ($orig != $new) {
730
			update_changedesc("{$varname}: \"{$orig}\" -> \"{$new}\"");
731
			$orig = $new;
732
			return true;
733
		}
734
	}
735
	return false;
736
}
737

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

    
754
	if (isset($adr['not'])) {
755
		$pnot = 1;
756
	} else {
757
		$pnot = 0;
758
	}
759

    
760
	if ($adr['port']) {
761
		list($pbeginport, $pendport) = explode("-", $adr['port']);
762
		if (!$pendport) {
763
			$pendport = $pbeginport;
764
		}
765
	} else if (!is_alias($pbeginport) && !is_alias($pendport)) {
766
		$pbeginport = "any";
767
		$pendport = "any";
768
	}
769
}
770

    
771
function pconfig_to_address(&$adr, $padr, $pmask, $pnot = false, $pbeginport = 0, $pendport = 0) {
772
	$adr = array();
773

    
774
	if ($padr == "any") {
775
		$adr['any'] = true;
776
	} else if (is_specialnet($padr)) {
777
		$adr['network'] = $padr;
778
	} else {
779
		$adr['address'] = $padr;
780
		if (is_ipaddrv6($padr)) {
781
			if ($pmask != 128) {
782
				$adr['address'] .= "/" . $pmask;
783
			}
784
		} else {
785
			if ($pmask != 32) {
786
				$adr['address'] .= "/" . $pmask;
787
			}
788
		}
789
	}
790

    
791
	if ($pnot) {
792
		$adr['not'] = true;
793
	} else {
794
		unset($adr['not']);
795
	}
796

    
797
	if (($pbeginport != 0) && ($pbeginport != "any")) {
798
		if ($pbeginport != $pendport) {
799
			$adr['port'] = $pbeginport . "-" . $pendport;
800
		} else {
801
			$adr['port'] = $pbeginport;
802
		}
803
	}
804

    
805
	if (is_alias($pbeginport)) {
806
		$adr['port'] = $pbeginport;
807
	}
808
}
809

    
810
function is_specialnet($net) {
811
	global $specialsrcdst;
812

    
813
	if (!$net) {
814
		return false;
815
	}
816
	if (in_array($net, $specialsrcdst)) {
817
		return true;
818
	} else {
819
		return false;
820
	}
821
}
822

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

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

    
852

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

    
865

    
866

    
867
function outputCSSPrintFileInline($css) {
868
	if (file_exists($css)) {
869
		echo "\n<style media=\"print\" type=\"text/css\">\n";
870
		include_once($css);
871
		echo "\n</style>\n";
872
	} else {
873
		echo "\n\n<!-- Could not locate file:  {$css} -->\n\n";
874
	}
875
}
876

    
877

    
878
function outputCSSFileInline($css) {
879
	if (file_exists($css)) {
880
		echo "\n<style type=\"text/css\">\n";
881
		include_once($css);
882
		echo "\n</style>\n";
883
	} else {
884
		echo "\n\n<!-- Could not locate file:  {$css} -->\n\n";
885
	}
886
}
887

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

    
932
function is_rfc2616_code($code) {
933
	global $rfc2616;
934
	if (isset($rfc2616[$code])) {
935
		return true;
936
	} else {
937
		return false;
938
	}
939
}
940

    
941
function print_rfc2616_select($tag, $current) {
942
	global $rfc2616;
943

    
944
	/* Default to 200 OK if not set */
945
	if ($current == "") {
946
		$current = 200;
947
	}
948

    
949
	echo "<select id=\"{$tag}\" name=\"{$tag}\">\n";
950
	foreach ($rfc2616 as $code => $message) {
951
		if ($code == $current) {
952
			$sel = " selected";
953
		} else {
954
			$sel = "";
955
		}
956
		echo "<option value=\"{$code}\"{$sel}>{$message}</option>\n";
957
	}
958
	echo "</select>\n";
959
}
960

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

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

    
1003
	/*	does the user have access to this tab?
1004
	 *	master user has access to everything.
1005
	 *	if the user does not have access, simply
1006
	 *	unset the tab item.
1007
	 */
1008

    
1009
	/* empty string code */
1010
	if ($tab_array_indent == '') {
1011
		$tab_array_indent = 0;
1012
	}
1013

    
1014
	if ($tab_array_space == '') {
1015
		$tab_array_space = 1;
1016
	}
1017

    
1018
	if ($tab_array_char_limit == '') {
1019
		$tab_array_char_limit = 92;
1020
	}
1021

    
1022
	foreach ($tab_array as $tab_id => $ta) {
1023
		if (!isAllowedPage($ta[2])) {
1024
			unset ($tab_array[$tab_id]);
1025
		}
1026
	}
1027

    
1028
	$tab_active_bg	 = "#EEEEEE";
1029
	$tab_inactive_bg = "#777777";
1030
	$nifty_tabs_corners = "#FFF";
1031
	$font_color = "white";
1032

    
1033
	$tabcharcount = 0;
1034
	foreach ($tab_array as $ta) {
1035
		$tabcharcount = $tabcharcount + strlen($ta[0]);
1036
	}
1037

    
1038
	if ($no_drop_down == true) {
1039
		$tabcharcount = 0;
1040
		unset($tab_array_char_limit);
1041
	}
1042

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

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

    
1060
		echo "</select>\n<p>&nbsp;</p>";
1061
		echo "<script type=\"text/javascript\">";
1062
		echo "\n//<![CDATA[\n";
1063
		if ($usepost == 'usepost') {
1064
			echo " function tabs_will_go(obj){ var target = obj.value.split(\"?\"); postSubmit(get2post(target[1]),target[0]); }\n";
1065
		} else {
1066
			echo " function tabs_will_go(obj){ document.location = obj.value; }\n";
1067
		}
1068
		echo "//]]>\n";
1069
		echo "</script>";
1070
	} else {
1071
		echo '<ul class="nav nav-' . $type . '">';
1072

    
1073
		foreach ($tab_array as $ta) {
1074
			echo '<li role="presentation"';
1075
			if ($ta[1]) {
1076
				echo ' class="active"';
1077
			}
1078

    
1079
			echo '><a href="' . $ta[2] . '" ' . $usepost . '>' . $ta[0] . '</a></li>';
1080
		}
1081

    
1082
		echo '</ul>';
1083
	}
1084
}
1085

    
1086
function add_package_tabs($tabgroup, &$tab_array) {
1087
	global $config, $g;
1088

    
1089
	if (!isset($config['installedpackages']['package'])) {
1090
		return;
1091
	}
1092

    
1093
	foreach ($config['installedpackages']['package'] as $pkg) {
1094
		$pkg_config = read_package_configurationfile($pkg['name']);
1095

    
1096
		if (!isset($pkg_config['tabs']['tab'])) {
1097
			continue;
1098
		}
1099

    
1100
		foreach ($pkg_config['tabs']['tab'] as $tab) {
1101
			$tab_entry = array();
1102
			if ($tab['name']) {
1103
				$tab_entry[] = $tab['name'];
1104
				$tab_entry[] = false;
1105
				$tab_entry[] = $tab['url'];
1106
				$tab_array[] = $tab_entry;
1107
			}
1108
		}
1109
	}
1110
}
1111

    
1112
function alias_info_popup($alias_id) {
1113
	global $config;
1114

    
1115
	if (!is_array($config['aliases']['alias'][$alias_id])) {
1116
		return;
1117
	}
1118

    
1119
	$maxlength = 60;
1120
	$alias = $config['aliases']['alias'][$alias_id];
1121
	$content = "";
1122

    
1123
	if ($alias['url']) {
1124
		// TODO: Change it when pf supports tables with ports
1125
		if ($alias['type'] == "urltable") {
1126
			exec("/sbin/pfctl -t {$alias['name']} -T show | wc -l", $total_entries);
1127
			$counter=preg_replace("/\D/", "", $total_entries[0]);
1128
			exec("/sbin/pfctl -t {$alias['name']} -T show | head -10002", $alias_addresses);
1129
		} else {
1130
			$urlfn = alias_expand_urltable($alias['name']);
1131
			$alias_addresses = explode("\n", file_get_contents($urlfn));
1132
			$counter = count($alias_addresses);
1133
		}
1134

    
1135
		$content .= '<h5>'. $alias['url'] .'</h5><ul><li>'. implode('</li><li>', $alias_addresses) .'</li></ul>';
1136
		if ($counter > 10002) {
1137
			$content .= '<i>'. gettext("listing only first 10k items") .'</i>';
1138
		}
1139
	} else {
1140
		$alias_addresses = explode (" ", $alias['address']);
1141
		$alias_details = explode ("||", $alias['detail']);
1142
		$idx = 0;
1143

    
1144
		$content .= "<table>\n";
1145
		$content .= "<thead>\n";
1146
		$content .= "<tr>\n";
1147
		$content .= "<th>" . gettext("Value") . "</th><th  style='padding-left: 10px;'>" . gettext("Description") . "</th></tr>\n";
1148
		$content .= "</thead>\n";
1149
		$content .= "<tbody>\n";
1150

    
1151
		foreach ($alias_addresses as $ap) {
1152
			$content .= "	<tr>\n";
1153
			$content .= "		<td>\n";
1154
			$content .= 			$ap;
1155
			$content .=	"		</td>\n";
1156
			$content .= "		<td style='padding-left: 10px;'>\n";
1157
			$content .= 			htmlspecialchars($alias_details[$idx]);
1158
			$content .=	"		</td>\n";
1159
			$content .= "	</tr>\n";
1160
			$idx++;
1161
		}
1162

    
1163
		$content .= "</tbody>\n";
1164
		$content .= "<table>\n";
1165
	}
1166

    
1167
	if (strlen($alias['descr']) >= $maxlength) {
1168
		$alias['descr'] = substr($alias['descr'], 0, $maxlength) . '&hellip;';
1169
	}
1170

    
1171
	return $content;
1172
}
1173

    
1174
function rule_columns_with_alias($src, $srcport, $dst, $dstport, $target="", $targetport="") {
1175
	global $config;
1176

    
1177
	if ($config['aliases']['alias'] == "" || !is_array($config['aliases']['alias'])) {
1178
		return;
1179
	}
1180

    
1181
	$columns = array();
1182
	foreach ($config['aliases']['alias'] as $alias_id => $alias_name) {
1183
		if ($alias_name['name'] == $src) {
1184
			$columns['src'] = $alias_id;
1185
		}
1186
		if ($alias_name['name'] == $srcport) {
1187
			$columns['srcport'] = $alias_id;
1188
		}
1189
		if ($alias_name['name'] == $dst) {
1190
			$columns['dst'] = $alias_id;
1191
		}
1192
		if ($alias_name['name'] == $dstport) {
1193
			$columns['dstport'] = $alias_id;
1194
		}
1195
		if ($alias_name['name'] == $target) {
1196
			$columns['target'] = $alias_id;
1197
		}
1198
		if ($alias_name['name'] == $targetport) {
1199
			$columns['targetport'] = $alias_id;
1200
		}
1201
	}
1202

    
1203
	return $columns;
1204
}
1205

    
1206
function form_output_row($name, $label, $content) {
1207
var_dump($content);die;
1208
?>
1209
<div class="form-group">
1210
	<label for="<?=$name?>" class="col-sm-2 control-label"><?=gettext($label); ?></label>
1211
	<div class="col-sm-10">
1212
		<?=$content?>
1213
	</div>
1214
</div>
1215
<?php
1216
}
1217

    
1218
function set_flash_message($class, $msg) {
1219
	@session_start();
1220
	$_SESSION['flash_messages'][$class][] = $msg;
1221
}
1222

    
1223
function get_flash_message() {
1224
	@session_start();
1225
	if (isset($_SESSION['flash_messages']) && !empty($_SESSION['flash_messages'])) {
1226
		foreach ($_SESSION['flash_messages'] as $class => $flash_message) {
1227
			print_info_box(implode("<br />", $flash_message), $class);
1228
		}
1229
		unset($_SESSION['flash_messages']);
1230
	}
1231
}
1232

    
1233
/* Retrieve GET or POST Value/State
1234
 * Eample Usage:
1235
 * $value = getGETPOSTsettingvalue('get/post parameter name', "");
1236
 * $value = getGETPOSTsettingvalue('get/post parameter name', null);
1237
 * $state = getGETPOSTsettingvalue('get/post parameter name', null);
1238
 * $state = getGETPOSTsettingvalue('get/post parameter name', false);
1239
 */
1240
function getGETPOSTsettingvalue($settingname, $default) {
1241
	$settingvalue = $default;
1242
	if ($_GET[$settingname]) {
1243
		$settingvalue = $_GET[$settingname];
1244
	}
1245
	if ($_POST[$settingname]) {
1246
		$settingvalue = $_POST[$settingname];
1247
	}
1248
	return $settingvalue;
1249
}
1250

    
1251
/* set timezone */
1252
if (isset($config['system']['timezone']) &&
1253
    !empty($config['system']['timezone'])) {
1254
	$timezone = $config['system']['timezone'];
1255
} elseif (isset($g['default_timezone']) && !empty($g['default_timezone'])) {
1256
	$timezone = $g['default_timezone'];
1257
} else {
1258
	$timezone = "Etc/UTC";
1259
}
1260

    
1261
date_default_timezone_set($timezone);
1262

    
1263
?>
(60-60/223)