Files
itflow/agent/modals/certificate/certificate_export.php
johnnyq e4c8130ebe Certificates: Check now connects to the host and saves what it serves - issuer, issued and expiry dates, names covered, SHA-256 fingerprint and the PEM - with the result (OK, name mismatch, untrusted, expired or unreachable) and when it ran, and a check that reaches nothing keeps the certificate on file; New/Edit form split into tabs (Certificate, Paste or by hand, Notes) with a Check button that shows what the host serves before saving, the host tidied from a pasted web address, the name defaulting to the host, the domain picked from the host and limited to the client's own, and a PEM paste or issuer and expiry by hand for hosts ITFlow can't reach; new certificate quick look with the check result and what to do about it, names covered, fingerprint copy, PEM copy and .crt download, domain, services, notes and history; certificates list rebuilt with All/Starred/Expiring soon/Expired/Problems/Not checked pills, host and names covered, domain link, issuer filter, last check column, whitelisted sort, ?open= and bulk check/star/archive/restore/delete; short-lived (ACME) certificates only count as expiring soon inside 20 days and skip the 45-day alert; domain and service quick looks link certificates to their quick look (with New certificate from a domain), global search finds certificates by name, host, names covered or fingerprint, client overview gets a Certificate problems box and renewals open the certificate, dashboard links to Expiring soon, client portal shows expiry badges, export adds last check, names covered, fingerprint and more, documentation PDF adds host and last check; certificate refresher now checks hosts daily in a time-boxed batch, writes history and notifies when an OK certificate turns bad; nightly alerts skip archived certificates and open the certificate; API create uses the same form rules and checks the host; demo data adds firewall, remote access and RADIUS certificates with real check results. Fixes the delete audit log using an undefined name, the archive flash type, certificates linking to another client's domain, services linking to another client's certificates, PEM parsing assuming an issuer organisation, and the API create using an undefined variable. DB 2.8.4
2026-10-15 01:07:32 -04:00

124 lines
5.1 KiB
PHP

<?php
require_once '../../../includes/modal_header.php';
enforceUserPermission('module_support');
// Pre-filled from the certificates page's current filters. Everything here is editable -
// the export runs whatever this form posts, not whatever the page happened to show.
$client_id = intval($_GET['client_id'] ?? 0);
if ($client_id) {
enforceClientAccess();
}
// Search Filter
$q_filter = $_GET['q'] ?? '';
// Client Filter
$client_filter = intval($_GET['client'] ?? 0);
// Expiring In Filter
$expire_filter = $_GET['expire_days'] ?? '';
// Problems Filter
$problems_filter = !empty($_GET['problems']) ? 1 : 0;
// Archived Filter
$archived_filter = (isset($_GET['archived']) && $_GET['archived'] == 1) ? 1 : 0;
ob_start();
?>
<div class="modal-header bg-dark">
<h5 class="modal-title"><i class="fas fa-fw fa-download me-2"></i>Export Certificates</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<?php exportTabsNav(); ?>
<form action="post.php" method="post" autocomplete="off">
<input type="hidden" name="csrf_token" value="<?= $_SESSION['csrf_token'] ?>">
<input type="hidden" name="client_id" value="<?= $client_id ?>">
<div class="modal-body">
<?php exportTabsFiltersOpen(); ?>
<div class="mb-3">
<label>Search</label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-search"></i></span>
<input type="text" class="form-control" name="q" value="<?= stripslashes(escapeHtml($q_filter)) ?>" placeholder="Name, host, names covered, issuer, fingerprint">
</div>
</div>
<?php if (!$client_id) { ?>
<div class="mb-3">
<label>Client</label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-user"></i></span>
<select class="form-select select2" name="client">
<option value="">- All Clients -</option>
<?php
$sql_clients_filter = mysqli_query($mysqli, "SELECT client_id, client_name, client_abbreviation FROM clients WHERE EXISTS (SELECT 1 FROM certificates WHERE certificate_client_id = client_id) ORDER BY client_name ASC");
while ($row = mysqli_fetch_assoc($sql_clients_filter)) {
$filter_client_id = intval($row['client_id']);
$filter_client_name = escapeHtml($row['client_name']);
?>
<option <?php if ($client_filter == $filter_client_id) { echo "selected"; } ?> value="<?= $filter_client_id ?>"<?= selectOptionClient($row['client_id'], $row['client_name'], $row['client_abbreviation'] ?? '') ?>><?= $filter_client_name ?></option>
<?php
}
?>
</select>
</div>
</div>
<?php } ?>
<div class="mb-3">
<label>Expiring In</label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-hourglass-half"></i></span>
<select class="form-select select2" name="expire_days">
<option value="">- Any -</option>
<option <?php if ($expire_filter === 'expired') { echo "selected"; } ?> value="expired">Expired</option>
<?php foreach ([7, 30, 45, 60, 90] as $expire_option) { ?>
<option <?php if ($expire_filter !== '' && $expire_filter == $expire_option) { echo "selected"; } ?> value="<?= $expire_option ?>"><?= $expire_option ?> Days</option>
<?php } ?>
</select>
</div>
</div>
<div class="mb-3">
<label>Last Check</label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-shield-alt"></i></span>
<select class="form-select select2" name="problems">
<option <?php if (!$problems_filter) { echo "selected"; } ?> value="0">- Any -</option>
<option <?php if ($problems_filter) { echo "selected"; } ?> value="1">Problems found - mismatch, untrusted, expired or unreachable</option>
</select>
</div>
</div>
<div class="mb-3">
<label>Archived</label>
<div class="input-group">
<span class="input-group-text"><i class="fa fa-fw fa-archive"></i></span>
<select class="form-select select2" name="archived">
<option <?php if (!$archived_filter) { echo "selected"; } ?> value="0">Active only</option>
<option <?php if ($archived_filter) { echo "selected"; } ?> value="1">Archived only</option>
</select>
</div>
</div>
<?php exportTabsColumns('certificates'); ?>
</div>
<div class="modal-footer">
<?php renderExportButtons('export_certificates'); ?>
</div>
</form>
<?php
require_once '../../../includes/modal_footer.php';