Project

General

Profile

Download (33.4 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
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *
16
 * 1. Redistributions of source code must retain the above copyright notice,
17
 *    this list of conditions and the following disclaimer.
18
 *
19
 * 2. Redistributions in binary form must reproduce the above copyright
20
 *    notice, this list of conditions and the following disclaimer in
21
 *    the documentation and/or other materials provided with the
22
 *    distribution.
23
 *
24
 * 3. All advertising materials mentioning features or use of this software
25
 *    must display the following acknowledgment:
26
 *    "This product includes software developed by the pfSense Project
27
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
28
 *
29
 * 4. The names "pfSense" and "pfSense Project" must not be used to
30
 *    endorse or promote products derived from this software without
31
 *    prior written permission. For written permission, please contact
32
 *    coreteam@pfsense.org.
33
 *
34
 * 5. Products derived from this software may not be called "pfSense"
35
 *    nor may "pfSense" appear in their names without prior written
36
 *    permission of the Electric Sheep Fencing, LLC.
37
 *
38
 * 6. Redistributions of any form whatsoever must retain the following
39
 *    acknowledgment:
40
 *
41
 * "This product includes software developed by the pfSense Project
42
 * for use in the pfSense software distribution (http://www.pfsense.org/).
43
 *
44
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
45
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
48
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55
 * OF THE POSSIBILITY OF SUCH DAMAGE.
56
 */
57

    
58
/* Include authentication routines */
59
/* THIS MUST BE ABOVE ALL OTHER CODE */
60
if (!$nocsrf) {
61
	function csrf_startup() {
62
		global $config;
63
		csrf_conf('rewrite-js', '/csrf/csrf-magic.js');
64
		$timeout_minutes = isset($config['system']['webgui']['session_timeout']) ? $config['system']['webgui']['session_timeout'] : 240;
65
		csrf_conf('expires', $timeout_minutes * 60);
66
	}
67
	require_once("csrf/csrf-magic.php");
68
}
69

    
70
/* make sure nothing is cached */
71
if (!$omit_nocacheheaders) {
72
	header("Expires: 0");
73
	header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
74
	header("Cache-Control: no-cache, no-store, must-revalidate");
75
	header("Pragma: no-cache");
76
}
77

    
78
header("X-Frame-Options: SAMEORIGIN");
79
require_once("authgui.inc");
80

    
81
/* parse the configuration and include all configuration functions */
82
require_once("functions.inc");
83

    
84
/* Include the autoloader for all the GUI display classes */
85
require_once("classes/autoload.inc.php");
86

    
87
/* used by progress bar */
88
$lastseen = "-1";
89

    
90
$navlevelsep = ": ";	/* navigation level separator string */
91
$mandfldhtml = "";		/* display this before mandatory input fields */
92
$mandfldhtmlspc = "";	/* same as above, but with spacing */
93

    
94
if (!function_exists('set_language')) {
95
	require_once("pfsense-utils.inc");
96
}
97

    
98
set_language();
99

    
100
/* Some ajax scripts still need access to GUI */
101
if (!$ignorefirmwarelock) {
102
	if (is_subsystem_dirty('firmwarelock')) {
103
		if (!$d_isfwfile) {
104
			header("Location: system_update.php");
105
			exit;
106
		} else {
107
			return;
108
		}
109
	}
110
}
111

    
112
/* Reserved table names to avoid collision */
113
$reserved_table_names = array(
114
	"bogons",
115
	"bogonsv6",
116
	"negate_networks",
117
	"snort2c",
118
	"sshlockout",
119
	"tonatsubnets",
120
	"virusprot",
121
	"vpn_networks",
122
	"webConfiguratorlockout"
123
);
124

    
125
$firewall_rules_dscp_types = array(
126
	"af11",
127
	"af12",
128
	"af13",
129
	"af21",
130
	"af22",
131
	"af23",
132
	"af31",
133
	"af32",
134
	"af33",
135
	"af41",
136
	"af42",
137
	"af43",
138
	"VA",
139
	"EF",
140
	"cs1",
141
	"cs2",
142
	"cs3",
143
	"cs4",
144
	"cs5",
145
	"cs6",
146
	"cs7",
147
	"0x01",
148
	"0x02",
149
	"0x04");
150

    
151
$auth_server_types = array(
152
	'ldap' => "LDAP",
153
	'radius' => "RADIUS");
154

    
155
$ldap_urltypes = array(
156
	'TCP - Standard' => 389,
157
	'TCP - STARTTLS' => 389,
158
	'SSL - Encrypted' => 636);
159

    
160
$ldap_scopes = array(
161
	'one' => gettext("One Level"),
162
	'subtree' => gettext("Entire Subtree"));
163

    
164
$ldap_protvers = array(
165
	2,
166
	3);
167

    
168
$ldap_templates = array(
169

    
170
	'open' => array(
171
		'desc' => "OpenLDAP",
172
		'attr_user' => "cn",
173
		'attr_group' => "cn",
174
		'attr_member' => "member"),
175

    
176
	'msad' => array(
177
		'desc' => "Microsoft AD",
178
		'attr_user' => "samAccountName",
179
		'attr_group' => "cn",
180
		'attr_member' => "memberOf"),
181

    
182
	'edir' => array(
183
		'desc' => "Novell eDirectory",
184
		'attr_user' => "cn",
185
		'attr_group' => "cn",
186
		'attr_member' => "uniqueMember"));
187

    
188
$radius_srvcs = array(
189
	'both' => gettext("Authentication and Accounting"),
190
	'auth' => gettext("Authentication"),
191
	'acct' => gettext("Accounting"));
192

    
193
$netbios_nodetypes = array(
194
	'0' => "none",
195
	'1' => "b-node",
196
	'2' => "p-node",
197
	'4' => "m-node",
198
	'8' => "h-node");
199

    
200
/* some well known ports */
201
$wkports = array(
202
	5999 => "CVSup",
203
	53 => "DNS",
204
	21 => "FTP",
205
	3000 => "HBCI",
206
	80 => "HTTP",
207
	443 => "HTTPS",
208
	5190 => "ICQ",
209
	113 => "IDENT/AUTH",
210
	143 => "IMAP",
211
	993 => "IMAP/S",
212
	4500 => "IPsec NAT-T",
213
	500 => "ISAKMP",
214
	1701 => "L2TP",
215
	389 => "LDAP",
216
	1755 => "MMS/TCP",
217
	7000 => "MMS/UDP",
218
	445 => "MS DS",
219
	3389 => "MS RDP",
220
	1512 => "MS WINS",
221
	1863 => "MSN",
222
	119 => "NNTP",
223
	123 => "NTP",
224
	138 => "NetBIOS-DGM",
225
	137 => "NetBIOS-NS",
226
	139 => "NetBIOS-SSN",
227
	1194 => "OpenVPN",
228
	110 => "POP3",
229
	995 => "POP3/S",
230
	1723 => "PPTP",
231
	1812 => "RADIUS",
232
	1813 => "RADIUS accounting",
233
	5004 => "RTP",
234
	5060 => "SIP",
235
	25 => "SMTP",
236
	465 => "SMTP/S",
237
	161 => "SNMP",
238
	162 => "SNMP-Trap",
239
	22 => "SSH",
240
	3478 => "STUN",
241
	587 => "SUBMISSION",
242
	3544 => "Teredo",
243
	23 => "Telnet",
244
	69 => "TFTP",
245
	5900 => "VNC");
246

    
247
/* TCP flags */
248
$tcpflags = array("fin", "syn", "rst", "psh", "ack", "urg", "ece", "cwr");
249

    
250
$specialnets = array(
251
	"(self)" => gettext("This Firewall"),
252
	"pppoe" => gettext("PPPoE clients"),
253
	"l2tp" => gettext("L2TP clients"));
254

    
255
$spiflist = get_configured_interface_with_descr(false, true);
256
foreach ($spiflist as $ifgui => $ifdesc) {
257
	$specialnets[$ifgui] = $ifdesc . " net";
258
	$specialnets[$ifgui . 'ip'] = $ifdesc . " address";
259
}
260

    
261
$medias = array(
262
	"auto" => gettext("autoselect"),
263
	"100full" => gettext("100BASE-TX full-duplex"),
264
	"100half" => gettext("100BASE-TX half-duplex"),
265
	"10full" => gettext("10BASE-T full-duplex"),
266
	"10half" => gettext("10BASE-T half-duplex"));
267

    
268
$wlan_modes = array(
269
	"bss" => gettext("Infrastructure (BSS)"),
270
	"adhoc" => gettext("Ad-hoc (IBSS)"),
271
	"hostap" => gettext("Access Point"));
272

    
273
function do_input_validation($postdata, $reqdfields, $reqdfieldsn, &$input_errors) {
274

    
275
	/* check for bad control characters */
276
	foreach ($postdata as $pn => $pd) {
277
		if (is_string($pd) && preg_match("/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/", $pd)) {
278
			$input_errors[] = sprintf(gettext("The field %s contains invalid characters."), $pn);
279
		}
280
	}
281

    
282
	for ($i = 0; $i < count($reqdfields); $i++) {
283
		if ($postdata[$reqdfields[$i]] == "") {
284
			$input_errors[] = sprintf(gettext("The field %s is required."), $reqdfieldsn[$i]);
285
		}
286
	}
287
}
288

    
289
function print_input_errors($input_errors) {
290
	echo '<div class="alert alert-danger input-errors">';
291
	echo '<p>' . gettext('The following input errors were detected:') . '</p>';
292
	echo '<ul>';
293

    
294
	foreach ($input_errors as $ierr) {
295
		echo '<li>' . htmlspecialchars($ierr) . '</li>';
296
	}
297

    
298
	echo '</ul>';
299
	echo '</div>';
300
}
301

    
302
function verify_gzip_file($fname) {
303
	$returnvar = mwexec("/usr/bin/gzip -t " . escapeshellarg($fname));
304
	if ($returnvar != 0) {
305
		return 0;
306
	} else {
307
		return 1;
308
	}
309
}
310

    
311
// print_info_box() has been updated so that any required button is explicitly created, rather than relying on the detection of certain
312
// strings in the message (such as "apply"). print_info_box_np() has been exterminated.
313
// $class = the bootstrap style class (default, info, warning, success, danger)
314
// $btnname and btntext describe the optional button and its display text, the default is an 'x' Close button.
315
// Note that there is also a shortcut function print_apply_box here that creates a standard "apply" box for you.
316
// In many cases just substitute that for print_info_box_np() to easily get a warning style "Apply changes" box.
317
function print_info_box($msg, $class="alert-warning", $btnname = "close", $btntext = "", $btnicon = "", $btnclass = "default") {
318

    
319
	if (strpos($class, "alert-") !== 0) {
320
		$class = 'alert-' . $class;
321
	}
322

    
323
	$msg = '<div class="pull-left">' . $msg . '</div>';
324

    
325
	if ($btnname === "close") {
326
		$msg = '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>' . $msg;
327
	} else if ($btnname != "") {
328
		if (empty($btntext)) {
329
			$btntext = $btnname;
330
		}
331
		if (!empty($btnicon)) {
332
			$btnicon = '<i class="fa ' . $btnicon . ' icon-embed-btn"></i>';
333
		}
334

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

    
337
		if ($_POST['if']) {
338
			$msg .= "<input type=\"hidden\" name=\"if\" value=\"" . htmlspecialchars($_POST['if']) . "\" />";
339
		}
340

    
341
		$msg .= '</form>';
342
	}
343

    
344
	echo '<div class="alert ' . $class . ' clearfix" role="alert">' . $msg . '</div>';
345
}
346

    
347
function print_apply_box($msg) {
348
	print_info_box($msg, "warning", "apply", gettext("Apply Changes"), 'fa-check', 'success');
349
}
350

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

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

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

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

    
378
function get_std_save_message($ok) {
379
	$filter_related = false;
380
	$filter_pages = array("nat", "filter");
381
	$to_return = gettext("The changes have been applied successfully.");
382
	foreach ($filter_pages as $fp) {
383
		if (stristr($_SERVER['SCRIPT_FILENAME'], $fp)) {
384
			$filter_related = true;
385
		}
386
	}
387
	if ($filter_related) {
388
		$to_return .= "<br />" . gettext("<a href=\"status_filter_reload.php\">Monitor</a> the filter reload progress.");
389
	}
390
	return $to_return;
391
}
392

    
393
function pprint_address($adr) {
394
	global $specialnets;
395

    
396
	if (isset($adr['any'])) {
397
		$padr = "*";
398
	} else if ($adr['network']) {
399
		$padr = $specialnets[$adr['network']];
400
	} else {
401
		$padr = $adr['address'];
402
	}
403

    
404
	if (isset($adr['not'])) {
405
		$padr = "! " . $padr;
406
	}
407

    
408
	return $padr;
409
}
410

    
411
function pprint_port($port) {
412
	global $wkports;
413

    
414
	$pport = "";
415

    
416
	if (!$port) {
417
		return "*";
418
	} else {
419
		$srcport = explode("-", $port);
420
		if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
421
			$pport = $srcport[0];
422
			if ($wkports[$srcport[0]]) {
423
				$pport .= " (" . $wkports[$srcport[0]] . ")";
424
			}
425
		} else {
426
			$pport .= $srcport[0] . " - " . $srcport[1];
427
		}
428
	}
429

    
430
	return $pport;
431
}
432

    
433
function insert_word_breaks_in_domain_name($domain_name) {
434
	return str_replace('.', '<wbr>.', $domain_name);
435
}
436

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

    
512
	return $item_set;
513
}
514

    
515
function gentitle($title) {
516
	global $navlevelsep;
517
	if (!is_array($title)) {
518
		return $title;
519
	} else {
520
		return join($navlevelsep, $title);
521
	}
522
}
523

    
524
function genhtmltitle($title, $links=true) {
525

    
526
	$num_crumbs = count($title);
527

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

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

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

    
559
		$bc .= '</ol>';
560
	} else {
561
		$bc = "";
562
	}
563

    
564
	return $bc;
565
}
566

    
567
/* update the changedesc and changecount(er) variables */
568
function update_changedesc($update) {
569
	global $changedesc;
570
	global $changecount;
571

    
572
	$changedesc .= " {$update}";
573
	$changecount++;
574
}
575

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

    
609
	$rows = 0;
610
	foreach ($logarr as $logent) {
611
		$rows++;
612
		$logent = preg_split("/\s+/", $logent, 6);
613

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

    
624
	}
625
	return($rows);
626
}
627

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

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

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

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

    
719
	} else {
720
		if ($orig != $new) {
721
			update_changedesc("{$varname}: \"{$orig}\" -> \"{$new}\"");
722
			$orig = $new;
723
			return true;
724
		}
725
	}
726
	return false;
727
}
728

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

    
745
	if (isset($adr['not'])) {
746
		$pnot = 1;
747
	} else {
748
		$pnot = 0;
749
	}
750

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

    
762
function pconfig_to_address(&$adr, $padr, $pmask, $pnot = false, $pbeginport = 0, $pendport = 0) {
763
	$adr = array();
764

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

    
782
	if ($pnot) {
783
		$adr['not'] = true;
784
	} else {
785
		unset($adr['not']);
786
	}
787

    
788
	if (($pbeginport != 0) && ($pbeginport != "any")) {
789
		if ($pbeginport != $pendport) {
790
			$adr['port'] = $pbeginport . "-" . $pendport;
791
		} else {
792
			$adr['port'] = $pbeginport;
793
		}
794
	}
795

    
796
	if (is_alias($pbeginport)) {
797
		$adr['port'] = $pbeginport;
798
	}
799
}
800

    
801
function is_specialnet($net) {
802
	global $specialsrcdst;
803

    
804
	if (!$net) {
805
		return false;
806
	}
807
	if (in_array($net, $specialsrcdst)) {
808
		return true;
809
	} else {
810
		return false;
811
	}
812
}
813

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

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

    
843

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

    
856

    
857

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

    
868

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

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

    
923
function is_rfc2616_code($code) {
924
	global $rfc2616;
925
	if (isset($rfc2616[$code])) {
926
		return true;
927
	} else {
928
		return false;
929
	}
930
}
931

    
932
function print_rfc2616_select($tag, $current) {
933
	global $rfc2616;
934

    
935
	/* Default to 200 OK if not set */
936
	if ($current == "") {
937
		$current = 200;
938
	}
939

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

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

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

    
994
	/*	does the user have access to this tab?
995
	 *	master user has access to everything.
996
	 *	if the user does not have access, simply
997
	 *	unset the tab item.
998
	 */
999

    
1000
	/* empty string code */
1001
	if ($tab_array_indent == '') {
1002
		$tab_array_indent = 0;
1003
	}
1004

    
1005
	if ($tab_array_space == '') {
1006
		$tab_array_space = 1;
1007
	}
1008

    
1009
	if ($tab_array_char_limit == '') {
1010
		$tab_array_char_limit = 92;
1011
	}
1012

    
1013
	foreach ($tab_array as $tab_id => $ta) {
1014
		if (!isAllowedPage($ta[2])) {
1015
			unset ($tab_array[$tab_id]);
1016
		}
1017
	}
1018

    
1019
	$tab_active_bg	 = "#EEEEEE";
1020
	$tab_inactive_bg = "#777777";
1021
	$nifty_tabs_corners = "#FFF";
1022
	$font_color = "white";
1023

    
1024
	$tabcharcount = 0;
1025
	foreach ($tab_array as $ta) {
1026
		$tabcharcount = $tabcharcount + strlen($ta[0]);
1027
	}
1028

    
1029
	if ($no_drop_down == true) {
1030
		$tabcharcount = 0;
1031
		unset($tab_array_char_limit);
1032
	}
1033

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

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

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

    
1060
		foreach ($tab_array as $ta) {
1061
			echo '<li role="presentation"';
1062
			if ($ta[1]) {
1063
				echo ' class="active"';
1064
			}
1065

    
1066
			echo '><a href="' . $ta[2] . '">' . $ta[0] . '</a></li>';
1067
		}
1068

    
1069
		echo '</ul>';
1070
	}
1071
}
1072

    
1073
function add_package_tabs($tabgroup, &$tab_array) {
1074
	global $config, $g;
1075

    
1076
	if (!isset($config['installedpackages']['package'])) {
1077
		return;
1078
	}
1079

    
1080
	foreach ($config['installedpackages']['package'] as $pkg) {
1081
		if (!is_array($pkg['tabs']['tab'])) {
1082
			continue;
1083
		}
1084

    
1085
		foreach ($pkg['tabs']['tab'] as $tab) {
1086
			if ($tab['tabgroup'] != $tabgroup) {
1087
				continue;
1088
			}
1089
			$tab_entry = array();
1090
			if ($tab['name']) {
1091
				$tab_entry[] = $tab['name'];
1092
				$tab_entry[] = false;
1093
				$tab_entry[] = $tab['url'];
1094
				$tab_array[] = $tab_entry;
1095
			}
1096
		}
1097
	}
1098
}
1099

    
1100
function alias_info_popup($alias_id) {
1101
	global $config;
1102

    
1103
	if (!is_array($config['aliases']['alias'][$alias_id])) {
1104
		return;
1105
	}
1106

    
1107
	$maxlength = 60;
1108
	$alias = $config['aliases']['alias'][$alias_id];
1109
	$content = "";
1110

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

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

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

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

    
1151
		$content .= "</tbody>\n";
1152
		$content .= "<table>\n";
1153
	}
1154

    
1155
	if (strlen($alias['descr']) >= $maxlength) {
1156
		$alias['descr'] = substr($alias['descr'], 0, $maxlength) . '&hellip;';
1157
	}
1158

    
1159
	return $content;
1160
}
1161

    
1162
function rule_columns_with_alias($src, $srcport, $dst, $dstport, $target="", $targetport="") {
1163
	global $config;
1164

    
1165
	if ($config['aliases']['alias'] == "" || !is_array($config['aliases']['alias'])) {
1166
		return;
1167
	}
1168

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

    
1191
	return $columns;
1192
}
1193

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

    
1206
function set_flash_message($class, $msg) {
1207
	@session_start();
1208
	$_SESSION['flash_messages'][$class][] = $msg;
1209
}
1210

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

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

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

    
1249
date_default_timezone_set($timezone);
1250

    
1251
?>
(61-61/225)