Project

General

Profile

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

    
517
	return $item_set;
518
}
519

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

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

    
531
	$num_crumbs = count($title);
532

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

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

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

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

    
569
	return $bc;
570
}
571

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
848

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

    
861

    
862

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

    
873

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1163
	return $content;
1164
}
1165

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

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

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

    
1195
	return $columns;
1196
}
1197

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

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

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

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

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

    
1253
date_default_timezone_set($timezone);
1254

    
1255
?>
(62-62/225)