Project

General

Profile

Download (33.8 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
include_once('phpsessionmanager.inc');
29
if (!$nocsrf) {
30
	function csrf_startup() {
31
		global $config;
32
		csrf_conf('rewrite-js', '/csrf/csrf-magic.js');
33
		$timeout_minutes = isset($config['system']['webgui']['session_timeout']) ? $config['system']['webgui']['session_timeout'] : 240;
34
		csrf_conf('expires', $timeout_minutes * 60);
35
	}
36
	require_once("csrf/csrf-magic.php");
37
	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
38
		phpsession_end(true);
39
	}
40
}
41

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

    
50
header("X-Frame-Options: SAMEORIGIN");
51
require_once("authgui.inc");
52

    
53
/* parse the configuration and include all configuration functions */
54
require_once("functions.inc");
55

    
56
/* Include the autoloader for all the GUI display classes */
57
require_once("classes/autoload.inc.php");
58

    
59
/* used by progress bar */
60
$lastseen = "-1";
61

    
62
$navlevelsep = ": ";	/* navigation level separator string */
63
$mandfldhtml = "";		/* display this before mandatory input fields */
64
$mandfldhtmlspc = "";	/* same as above, but with spacing */
65

    
66
if (!function_exists('set_language')) {
67
	require_once("pfsense-utils.inc");
68
}
69

    
70
set_language();
71

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

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

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

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

    
127
$ldap_urltypes = array(
128
	'TCP - Standard' => 389,
129
	'TCP - STARTTLS' => 389,
130
	'SSL - Encrypted' => 636);
131

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

    
136
$ldap_protvers = array(
137
	2,
138
	3);
139

    
140
$ldap_templates = array(
141

    
142
	'open' => array(
143
		'desc' => "OpenLDAP",
144
		'attr_user' => "cn",
145
		'attr_group' => "cn",
146
		'attr_member' => "member"),
147

    
148
	'msad' => array(
149
		'desc' => "Microsoft AD",
150
		'attr_user' => "samAccountName",
151
		'attr_group' => "cn",
152
		'attr_member' => "memberOf"),
153

    
154
	'edir' => array(
155
		'desc' => "Novell eDirectory",
156
		'attr_user' => "cn",
157
		'attr_group' => "cn",
158
		'attr_member' => "uniqueMember"));
159

    
160
$radius_srvcs = array(
161
	'both' => gettext("Authentication and Accounting"),
162
	'auth' => gettext("Authentication"),
163
	'acct' => gettext("Accounting"));
164

    
165
$radius_protocol = array(
166
	'PAP' => "PAP",
167
	'CHAP_MD5' => "MD5-CHAP",
168
	'MSCHAPv1' => "MS-CHAPv1",
169
	'MSCHAPv2' => "MS-CHAPv2");
170

    
171
$netbios_nodetypes = array(
172
	'0' => "none",
173
	'1' => "b-node",
174
	'2' => "p-node",
175
	'4' => "m-node",
176
	'8' => "h-node");
177

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

    
225
/* TCP flags */
226
$tcpflags = array("fin", "syn", "rst", "psh", "ack", "urg", "ece", "cwr");
227

    
228
$specialnets = array(
229
	"(self)" => gettext("This Firewall"),
230
	"pppoe" => gettext("PPPoE clients"),
231
	"l2tp" => gettext("L2TP clients"));
232

    
233
$spiflist = get_configured_interface_with_descr(false, true);
234
foreach ($spiflist as $ifgui => $ifdesc) {
235
	$specialnets[$ifgui] = $ifdesc . " net";
236
	$specialnets[$ifgui . 'ip'] = $ifdesc . " address";
237
}
238

    
239
$medias = array(
240
	"auto" => gettext("autoselect"),
241
	"100full" => gettext("100BASE-TX full-duplex"),
242
	"100half" => gettext("100BASE-TX half-duplex"),
243
	"10full" => gettext("10BASE-T full-duplex"),
244
	"10half" => gettext("10BASE-T half-duplex"));
245

    
246
$wlan_modes = array(
247
	"bss" => gettext("Infrastructure (BSS)"),
248
	"adhoc" => gettext("Ad-hoc (IBSS)"),
249
	"hostap" => gettext("Access Point"));
250

    
251
function do_input_validation($postdata, $reqdfields, $reqdfieldsn, &$input_errors) {
252

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

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

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

    
272
	foreach ($input_errors as $ierr) {
273
		echo '<li>' . htmlspecialchars($ierr) . '</li>';
274
	}
275

    
276
	echo '</ul>';
277
	echo '</div>';
278
}
279

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

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

    
299
	if (strpos($class, "alert-") !== 0) {
300
		$class = 'alert-' . $class;
301
	}
302

    
303
	$msg = '<div class="pull-left">' . $msg . '</div>';
304

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

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

    
317
		if ($_POST['if']) {
318
			$msg .= "<input type=\"hidden\" name=\"if\" value=\"" . htmlspecialchars($_POST['if']) . "\" />";
319
		}
320

    
321
		$msg .= '</form>';
322
	}
323

    
324
	return '<div class="alert ' . $class . ' clearfix" role="alert">' . $msg . '</div>';
325
}
326

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

    
332
function print_apply_box($msg) {
333
	print_info_box($msg, "warning", "apply", gettext("Apply Changes"), 'fa-check', 'success');
334
}
335

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

    
351
	if (strlen($extra_text) > 0) {
352
		$result_msg .= " " . $extra_text;
353
	}
354
	print_info_box($result_msg, $severity);
355
}
356

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

    
366
	if ('' == $msg) {
367
		return;
368
	}
369
	$class = strtolower($class);
370
	$callout = '';
371

    
372
	if ($class != 'default' && $class != 'danger' && $class != 'warning' && $class != 'info') {
373
		$class = 'info';
374
	}
375
	$callout .= '<div class="bs-callout bs-callout-' . $class . '">';
376

    
377
	if ('' != $heading) {
378
		$callout .= '<h4>' . $heading . '</h4>';
379
	}
380
	$callout .= $msg . '</div>';
381
	echo $callout;
382
}
383

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

    
406
function pprint_address($adr) {
407
	global $specialnets;
408

    
409
	if (isset($adr['any'])) {
410
		$padr = "*";
411
	} else if ($adr['network']) {
412
		$padr = $specialnets[$adr['network']];
413
	} else {
414
		$padr = $adr['address'];
415
	}
416

    
417
	if (isset($adr['not'])) {
418
		$padr = "! " . $padr;
419
	}
420

    
421
	return $padr;
422
}
423

    
424
function pprint_port($port) {
425
	global $wkports;
426

    
427
	$pport = "";
428

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

    
443
	return $pport;
444
}
445

    
446
function insert_word_breaks_in_domain_name($domain_name) {
447
	return str_replace('.', '<wbr>.', $domain_name);
448
}
449

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

    
525
	return $item_set;
526
}
527

    
528
function gentitle($title) {
529
	global $navlevelsep;
530
	if (!is_array($title)) {
531
		return $title;
532
	} else {
533
		return join($navlevelsep, $title);
534
	}
535
}
536

    
537
function genhtmltitle($title, $links=true) {
538

    
539
	$num_crumbs = count($title);
540

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

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

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

    
572
		$bc .= '</ol>';
573
	} else {
574
		$bc = "";
575
	}
576

    
577
	return $bc;
578
}
579

    
580
/* update the changedesc and changecount(er) variables */
581
function update_changedesc($update) {
582
	global $changedesc;
583
	global $changecount;
584

    
585
	$changedesc .= " {$update}";
586
	$changecount++;
587
}
588

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

    
622
	$rows = 0;
623
	foreach ($logarr as $logent) {
624
		$rows++;
625
		$logent = preg_split("/\s+/", $logent, 6);
626

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

    
637
	}
638
	return($rows);
639
}
640

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

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

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

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

    
732
	} else {
733
		if ($orig != $new) {
734
			update_changedesc("{$varname}: \"{$orig}\" -> \"{$new}\"");
735
			$orig = $new;
736
			return true;
737
		}
738
	}
739
	return false;
740
}
741

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

    
758
	if (isset($adr['not'])) {
759
		$pnot = 1;
760
	} else {
761
		$pnot = 0;
762
	}
763

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

    
775
function pconfig_to_address(&$adr, $padr, $pmask, $pnot = false, $pbeginport = 0, $pendport = 0) {
776
	$adr = array();
777

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

    
795
	if ($pnot) {
796
		$adr['not'] = true;
797
	} else {
798
		unset($adr['not']);
799
	}
800

    
801
	if (($pbeginport != 0) && ($pbeginport != "any")) {
802
		if ($pbeginport != $pendport) {
803
			$adr['port'] = $pbeginport . "-" . $pendport;
804
		} else {
805
			$adr['port'] = $pbeginport;
806
		}
807
	}
808

    
809
	if (is_alias($pbeginport)) {
810
		$adr['port'] = $pbeginport;
811
	}
812
}
813

    
814
function is_specialnet($net) {
815
	global $specialsrcdst;
816

    
817
	if (!$net) {
818
		return false;
819
	}
820
	if (in_array($net, $specialsrcdst)) {
821
		return true;
822
	} else {
823
		return false;
824
	}
825
}
826

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

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

    
856

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

    
869

    
870

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

    
881

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

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

    
936
function is_rfc2616_code($code) {
937
	global $rfc2616;
938
	if (isset($rfc2616[$code])) {
939
		return true;
940
	} else {
941
		return false;
942
	}
943
}
944

    
945
function print_rfc2616_select($tag, $current) {
946
	global $rfc2616;
947

    
948
	/* Default to 200 OK if not set */
949
	if ($current == "") {
950
		$current = 200;
951
	}
952

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

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

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

    
1007
	/*	does the user have access to this tab?
1008
	 *	master user has access to everything.
1009
	 *	if the user does not have access, simply
1010
	 *	unset the tab item.
1011
	 */
1012

    
1013
	/* empty string code */
1014
	if ($tab_array_indent == '') {
1015
		$tab_array_indent = 0;
1016
	}
1017

    
1018
	if ($tab_array_space == '') {
1019
		$tab_array_space = 1;
1020
	}
1021

    
1022
	if ($tab_array_char_limit == '') {
1023
		$tab_array_char_limit = 92;
1024
	}
1025

    
1026
	foreach ($tab_array as $tab_id => $ta) {
1027
		if (!isAllowedPage($ta[2])) {
1028
			unset ($tab_array[$tab_id]);
1029
		}
1030
	}
1031

    
1032
	$tab_active_bg	 = "#EEEEEE";
1033
	$tab_inactive_bg = "#777777";
1034
	$nifty_tabs_corners = "#FFF";
1035
	$font_color = "white";
1036

    
1037
	$tabcharcount = 0;
1038
	foreach ($tab_array as $ta) {
1039
		$tabcharcount = $tabcharcount + strlen($ta[0]);
1040
	}
1041

    
1042
	if ($no_drop_down == true) {
1043
		$tabcharcount = 0;
1044
		unset($tab_array_char_limit);
1045
	}
1046

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

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

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

    
1077
		foreach ($tab_array as $ta) {
1078
			echo '<li role="presentation"';
1079
			if ($ta[1]) {
1080
				echo ' class="active"';
1081
			}
1082

    
1083
			echo '><a href="' . $ta[2] . '" ' . $usepost . '>' . $ta[0] . '</a></li>';
1084
		}
1085

    
1086
		echo '</ul>';
1087
	}
1088
}
1089

    
1090
function add_package_tabs($tabgroup, &$tab_array) {
1091
	global $config, $g;
1092

    
1093
	if (!isset($config['installedpackages']['package'])) {
1094
		return;
1095
	}
1096

    
1097
	foreach ($config['installedpackages']['package'] as $pkg) {
1098
		if (!is_array($pkg['tabs']['tab'])) {
1099
			continue;
1100
		}
1101

    
1102
		foreach ($pkg['tabs']['tab'] as $tab) {
1103
			if ($tab['tabgroup'] != $tabgroup) {
1104
				continue;
1105
			}
1106
			$tab_entry = array();
1107
			if ($tab['name']) {
1108
				$tab_entry[] = $tab['name'];
1109
				$tab_entry[] = false;
1110
				$tab_entry[] = $tab['url'];
1111
				$tab_array[] = $tab_entry;
1112
			}
1113
		}
1114
	}
1115
}
1116

    
1117
function alias_info_popup($alias_id) {
1118
	global $config, $user_settings;
1119

    
1120
	if (!is_array($config['aliases']['alias'][$alias_id])) {
1121
		return;
1122
	}
1123

    
1124
	$maxlength = 60;
1125
	$alias = $config['aliases']['alias'][$alias_id];
1126
	$content = "";
1127

    
1128
	if ($user_settings['webgui']['disablealiaspopupdetail']) {
1129
		if (strlen($alias['descr']) >= $maxlength) {
1130
			$alias['descr'] = substr($alias['descr'], 0, $maxlength) . '&hellip;';
1131
		}
1132

    
1133
		$content .= $alias['descr'];
1134
	} else if ($alias['url']) {
1135
		// TODO: Change it when pf supports tables with ports
1136
		if ($alias['type'] == "urltable") {
1137
			exec("/sbin/pfctl -t {$alias['name']} -T show | wc -l", $total_entries);
1138
			$counter=preg_replace("/\D/", "", $total_entries[0]);
1139
			exec("/sbin/pfctl -t {$alias['name']} -T show | head -10002", $alias_addresses);
1140
		} else {
1141
			$urlfn = alias_expand_urltable($alias['name']);
1142
			$alias_addresses = explode("\n", file_get_contents($urlfn));
1143
			$counter = count($alias_addresses);
1144
		}
1145

    
1146
		$content .= '<h5>'. $alias['url'] .'</h5><ul><li>'. implode('</li><li>', $alias_addresses) .'</li></ul>';
1147
		if ($counter > 10002) {
1148
			$content .= '<i>'. gettext("listing only first 10k items") .'</i>';
1149
		}
1150
	} else {
1151
		$alias_addresses = explode (" ", $alias['address']);
1152
		$alias_details = explode ("||", $alias['detail']);
1153
		$idx = 0;
1154

    
1155
		$content .= "<table>\n";
1156
		$content .= "<thead>\n";
1157
		$content .= "<tr>\n";
1158
		$content .= "<th>" . gettext("Value") . "</th><th  style='padding-left: 10px;'>" . gettext("Description") . "</th></tr>\n";
1159
		$content .= "</thead>\n";
1160
		$content .= "<tbody>\n";
1161

    
1162
		foreach ($alias_addresses as $ap) {
1163
			$content .= "	<tr>\n";
1164
			$content .= "		<td>\n";
1165
			$content .= 			$ap;
1166
			$content .=	"		</td>\n";
1167
			$content .= "		<td style='padding-left: 10px;'>\n";
1168
			$content .= 			htmlspecialchars($alias_details[$idx]);
1169
			$content .=	"		</td>\n";
1170
			$content .= "	</tr>\n";
1171
			$idx++;
1172
		}
1173

    
1174
		$content .= "</tbody>\n";
1175
		$content .= "<table>\n";
1176
	}
1177

    
1178
	return $content;
1179
}
1180

    
1181
function rule_columns_with_alias($src, $srcport, $dst, $dstport, $target="", $targetport="") {
1182
	global $config;
1183

    
1184
	if ($config['aliases']['alias'] == "" || !is_array($config['aliases']['alias'])) {
1185
		return;
1186
	}
1187

    
1188
	$columns = array();
1189
	foreach ($config['aliases']['alias'] as $alias_id => $alias_name) {
1190
		if ($alias_name['name'] == $src) {
1191
			$columns['src'] = $alias_id;
1192
		}
1193
		if ($alias_name['name'] == $srcport) {
1194
			$columns['srcport'] = $alias_id;
1195
		}
1196
		if ($alias_name['name'] == $dst) {
1197
			$columns['dst'] = $alias_id;
1198
		}
1199
		if ($alias_name['name'] == $dstport) {
1200
			$columns['dstport'] = $alias_id;
1201
		}
1202
		if ($alias_name['name'] == $target) {
1203
			$columns['target'] = $alias_id;
1204
		}
1205
		if ($alias_name['name'] == $targetport) {
1206
			$columns['targetport'] = $alias_id;
1207
		}
1208
	}
1209

    
1210
	return $columns;
1211
}
1212

    
1213
function form_output_row($name, $label, $content) {
1214
var_dump($content);die;
1215
?>
1216
<div class="form-group">
1217
	<label for="<?=$name?>" class="col-sm-2 control-label"><?=gettext($label); ?></label>
1218
	<div class="col-sm-10">
1219
		<?=$content?>
1220
	</div>
1221
</div>
1222
<?php
1223
}
1224

    
1225
function set_flash_message($class, $msg) {
1226
	@phpsession_begin();
1227
	$_SESSION['flash_messages'][$class][] = $msg;
1228
	@phpsession_end(true);
1229
}
1230

    
1231
function get_flash_message() {
1232
	@phpsession_begin();
1233
	if (isset($_SESSION['flash_messages']) && !empty($_SESSION['flash_messages'])) {
1234
		foreach ($_SESSION['flash_messages'] as $class => $flash_message) {
1235
			print_info_box(implode("<br />", $flash_message), $class);
1236
		}
1237
		unset($_SESSION['flash_messages']);
1238
	}
1239
	@phpsession_end(true);
1240
}
1241

    
1242
/* Retrieve GET or POST Value/State
1243
 * Eample Usage:
1244
 * $value = getGETPOSTsettingvalue('get/post parameter name', "");
1245
 * $value = getGETPOSTsettingvalue('get/post parameter name', null);
1246
 * $state = getGETPOSTsettingvalue('get/post parameter name', null);
1247
 * $state = getGETPOSTsettingvalue('get/post parameter name', false);
1248
 */
1249
function getGETPOSTsettingvalue($settingname, $default) {
1250
	$settingvalue = $default;
1251
	if ($_GET[$settingname]) {
1252
		$settingvalue = $_GET[$settingname];
1253
	}
1254
	if ($_POST[$settingname]) {
1255
		$settingvalue = $_POST[$settingname];
1256
	}
1257
	return $settingvalue;
1258
}
1259

    
1260
/* set timezone */
1261
if (isset($config['system']['timezone']) &&
1262
    !empty($config['system']['timezone'])) {
1263
	$timezone = $config['system']['timezone'];
1264
} elseif (isset($g['default_timezone']) && !empty($g['default_timezone'])) {
1265
	$timezone = $g['default_timezone'];
1266
} else {
1267
	$timezone = "Etc/UTC";
1268
}
1269

    
1270
date_default_timezone_set($timezone);
1271

    
1272
?>
(60-60/223)