%PDF- %PDF-
| Direktori : /proc/self/root/backups/router/usr/local/www/ |
| Current File : //proc/self/root/backups/router/usr/local/www/crash_reporter.php |
<?php
/*
* Copyright (C) 2015-2023 Franco Fichtner <franco@opnsense.org>
* Copyright (C) 2014 Deciso B.V.
* Copyright (C) 2011 Scott Ullrich <sullrich@gmail.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
require_once 'guiconfig.inc';
function has_crash_report()
{
$skip_files = ['.', '..', 'minfree', 'bounds', ''];
$PHP_errors_log = '/tmp/PHP_errors.log';
$count = 0;
if (file_exists($PHP_errors_log) && !is_link('/tmp/PHP_errors.log')) {
if (intval(shell_safe('/bin/cat %s | /usr/bin/wc -l | /usr/bin/awk \'{ print $1 }\'', $PHP_errors_log))) {
$count++;
}
}
$crashes = glob('/var/crash/*');
foreach ($crashes as $crash) {
if (!in_array(basename($crash), $skip_files)) {
$count++;
}
}
return $count;
}
function upload_crash_report($files, $agent)
{
$post = array();
$counter = 0;
foreach ($files as $filename) {
if (is_link($filename) || $filename == '/var/crash/minfree.gz' || $filename == '/var/crash/bounds.gz'
|| filesize($filename) > 5 * 1024 * 1024) {
continue;
}
$post["file{$counter}"] = curl_file_create($filename, "application/x-gzip", basename($filename));
$counter++;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://crash.opnsense.org/');
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_VERBOSE, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: multipart/form-data;' ));
$response = curl_exec($ch);
curl_close($ch);
return !$response;
}
include('head.inc');
$plugins = implode(' ', explode("\n", shell_safe('/usr/local/sbin/pkg-static info -g "os-*"')));
$product = product::getInstance();
$crash_report_header = sprintf(
"%s %s\n%s %s %s\n%sTime %s\n%s\n%s\nPHP %s\n",
php_uname('v'),
$product->arch(),
$product->name(),
$product->version(),
$product->hash(),
empty($plugins) ? '' : "Plugins $plugins\n",
date('r'),
shell_safe('/usr/local/bin/openssl version | cut -f -2 -d \' \''),
shell_safe('/usr/local/bin/python3 -V'),
PHP_VERSION
);
if (isset($_SERVER['HTTP_USER_AGENT'])) {
$crash_report_header = "User-Agent {$_SERVER['HTTP_USER_AGENT']}\n{$crash_report_header}";
}
$user_agent = "{$product->name()}/{$product->version()}";
$crash_reports = [];
$has_crashed = false;
$is_prod = empty($config['system']['deployment']);
$pconfig = array();
$pconfig['Email'] = isset($config['system']['contact_email']) ? $config['system']['contact_email'] : '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pconfig = $_POST;
if ($pconfig['Submit'] == 'yes') {
if (!is_dir('/var/crash')) {
mkdir('/var/crash', 0750, true);
}
$email = trim($pconfig['Email']);
if (!empty($email)) {
$crash_report_header .= "Email {$email}\n";
if (!isset($config['system']['contact_email']) ||
$config['system']['contact_email'] !== $email) {
$config['system']['contact_email'] = $email;
write_config('Updated crash reporter contact email.');
}
} elseif (isset($config['system']['contact_email'])) {
unset($config['system']['contact_email']);
write_config('Removed crash reporter contact email.');
}
$desc = trim($pconfig['Desc']);
if (!empty($desc)) {
$crash_report_header .= "Description\n\n{$desc}";
}
$skip_files = array('.', '..', 'minfree', 'bounds', '');
$crashes = glob('/var/crash/*');
foreach ($crashes as $crash) {
if (!in_array(basename($crash), $skip_files)) {
$count++;
}
}
if ($count || (!empty($desc) && !empty($email))) {
$files_to_upload = glob('/var/crash/*');
foreach ($files_to_upload as $file_to_upload) {
if (filesize($file_to_upload) > 450000) {
@unlink($file_to_upload);
}
}
file_put_contents('/var/crash/crashreport_header.txt', $crash_report_header);
if (file_exists('/tmp/PHP_errors.log')) {
// limit PHP_errors to send to 1MB
exec('/usr/bin/tail -c 1048576 /tmp/PHP_errors.log > /var/crash/PHP_errors.log');
@unlink('/tmp/PHP_errors.log');
}
@copy('/var/run/dmesg.boot', '/var/crash/dmesg.boot');
exec('/usr/bin/gzip /var/crash/*');
$files_to_upload = glob('/var/crash/*');
upload_crash_report($files_to_upload, $user_agent);
foreach ($files_to_upload as $file_to_upload) {
@unlink($file_to_upload);
}
} else {
/* still crashing ;) */
$has_crashed = true;
}
} elseif ($pconfig['Submit'] == 'no') {
$files_to_upload = glob('/var/crash/*');
foreach ($files_to_upload as $file_to_upload) {
@unlink($file_to_upload);
}
@unlink('/tmp/PHP_errors.log');
} elseif ($pconfig['Submit'] == 'new') {
/* force a crash report generation */
$has_crashed = true;
}
} else {
/* if there is no user activity probe for a crash report */
$has_crashed = has_crash_report();
}
if ($has_crashed) {
$crash_files = glob("/var/crash/*");
$crash_reports['System Information'] = trim($crash_report_header);
if (file_exists('/tmp/PHP_errors.log') && !is_link('/tmp/PHP_errors.log')) {
$php_errors_size = @filesize('/tmp/PHP_errors.log');
$max_php_errors_size = 1 * 1024 * 1024;
// limit reporting for PHP_errors.log to $max_php_errors_size characters
if ($php_errors_size > $max_php_errors_size) {
// if file is to large, only display last $max_php_errors_size characters
$php_errors .= @file_get_contents(
'/tmp/PHP_errors.log',
NULL,
NULL,
($php_errors_size - $max_php_errors_size),
$max_php_errors_size
);
} else {
$php_errors = @file_get_contents('/tmp/PHP_errors.log');
}
if (!empty($php_errors)) {
$crash_reports['PHP Errors'] = trim($php_errors);
}
}
$dmesg_boot = @file_get_contents('/var/run/dmesg.boot');
if (!empty($dmesg_boot)) {
$crash_reports['dmesg.boot'] = trim($dmesg_boot);
}
foreach ($crash_files as $cf) {
if (!is_link($cf) && $cf != '/var/crash/minfree' && $cf != '/var/crash/bounds') {
if (filesize($cf) > 450000) {
$crash_reports[$cf] = gettext('File too big to process. It will not be submitted automatically.');
} else {
$crash_reports[$cf] = trim(file_get_contents($cf));
}
}
}
}
$message = gettext('No issues were detected.');
if ($has_crashed) {
if ($is_prod) {
$message = gettext('An issue was detected.');
} else {
$message = gettext('Development deployment is configured so crash reports cannot be sent.');
}
}
if (isset($pconfig['Submit'])) {
if ($pconfig['Submit'] == 'yes') {
if (!$has_crashed) {
$message = gettext('Thank you for submitting this crash report.');
} else {
$message = gettext('This crash report contains no actual crash information. If you want to submit a problem please fill out your e-mail and description below.');
}
} elseif ($pconfig['Submit'] == 'no') {
if ($is_prod) {
$message = gettext('Please consider submitting a crash report if the error persists.');
}
}
}
// escape form output before processing
legacy_html_escape_form_data($pconfig);
?>
<body>
<?php include("fbegin.inc"); ?>
<section class="page-content-main">
<div class="container-fluid">
<div class="row">
<section class="col-xs-12">
<div class="content-box">
<form method="post">
<div class="col-xs-12">
<?php if ($has_crashed): ?>
<br/><button name="Submit" type="submit" class="btn btn-default pull-right" value="no"><?=gettext('Dismiss this report');?></button>
<?php if ($is_prod): ?>
<button name="Submit" type="submit" class="btn btn-primary pull-right" style="margin-right: 8px;" value="yes"><?=gettext('Submit this report');?></button>
<p><strong><?= $message ?></strong></p>
<p><?=gettext("Would you like to submit this crash report to the developers?");?></p>
<hr><p><?=gettext('You can help us further by adding your contact information and a problem description. ' .
'Please note that providing your contact information greatly improves the chances of bugs being fixed.');?></p>
<p><input type="text" placeholder="<?= html_safe(gettext('your@email.com')) ?>" name="Email" value="<?= html_safe($pconfig['Email']) ?>"></p>
<p><textarea rows="5" placeholder="<?= html_safe(gettext('A short problem description or steps to reproduce.')) ?>" name="Desc"><?= $pconfig['Desc'] ?></textarea></p>
<hr><p><?=gettext("Please double-check the following contents to ensure you are comfortable submitting the following information.");?></p>
<?php else: ?>
<p><strong><?= $message ?></strong></p>
<?php endif ?>
<?php
foreach ($crash_reports as $report => $content):?>
<p>
<?=$report;?>:<br/>
<pre><?=html_safe($content);?></pre>
</p>
<?php
endforeach;
else:?>
<input type="hidden" name="Email" value="<?= html_safe($pconfig['Email'] ?? '') ?>">
<br/><button name="Submit" type="submit" class="btn btn-primary pull-right" value="new"><?=gettext('Report an issue');?></button>
<p><strong><?=$message;?></strong></p><br/>
<?php
endif;?>
</div>
</form>
</div>
</section>
</div>
</div>
</section>
<?php include("foot.inc");