mirror of
https://github.com/pfsense/pfsense.git
synced 2025-10-26 11:38:35 +00:00
CRL management overhaul
* Allow revoking by serial number or cert. Implements #9869 * Allow revoking multiple entries at a time. Implements #3258 * Declutter the main CRL list screen * Move the create control to the bottom under the list * Various other efficiency/style improvements
This commit is contained in:
parent
8d4663c138
commit
63fb68d713
@ -1012,10 +1012,18 @@ function crl_update(& $crl) {
|
||||
|
||||
if (is_array($crl['cert']) && (count($crl['cert']) > 0)) {
|
||||
foreach ($crl['cert'] as $cert) {
|
||||
/* Determine the serial number to revoke */
|
||||
if (isset($cert['serial'])) {
|
||||
$serial = $cert['serial'];
|
||||
} elseif (isset($cert['crt'])) {
|
||||
$serial = cert_get_serial($cert['crt'], true);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
$crlconf['revoked'][] = array(
|
||||
'serial' => cert_get_serial($cert["crt"], true),
|
||||
'rev_date' => $cert["revoke_time"],
|
||||
'reason' => ($cert["reason"] == -1) ? null : (int) $cert["reason"],
|
||||
'serial' => $serial,
|
||||
'rev_date' => $cert['revoke_time'],
|
||||
'reason' => ($cert['reason'] == -1) ? null : (int) $cert['reason'],
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -1035,9 +1043,21 @@ function cert_revoke($cert, & $crl, $reason = OCSP_REVOKED_STATUS_UNSPECIFIED) {
|
||||
if (!is_crl_internal($crl)) {
|
||||
return false;
|
||||
}
|
||||
$cert["reason"] = $reason;
|
||||
$cert["revoke_time"] = time();
|
||||
$crl["cert"][] = $cert;
|
||||
|
||||
if (!is_array($cert)) {
|
||||
/* If passed a not an array but a serial string, set it up as an
|
||||
* array with the serial number defined */
|
||||
$rcert = array();
|
||||
$rcert['serial'] = $cert;
|
||||
} else {
|
||||
/* If passed a certificate entry, read out the serial and store
|
||||
* it separately. */
|
||||
$rcert = $cert;
|
||||
$rcert['serial'] = cert_get_serial($cert['crt']);
|
||||
}
|
||||
$rcert['reason'] = $reason;
|
||||
$rcert['revoke_time'] = time();
|
||||
$crl['cert'][] = $rcert;
|
||||
crl_update($crl);
|
||||
return true;
|
||||
}
|
||||
@ -1047,8 +1067,14 @@ function cert_unrevoke($cert, & $crl) {
|
||||
if (!is_crl_internal($crl)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$serial = crl_get_entry_serial($cert);
|
||||
|
||||
foreach ($crl['cert'] as $id => $rcert) {
|
||||
if (($rcert['refid'] == $cert['refid']) || ($rcert['descr'] == $cert['descr'])) {
|
||||
/* Check for a match by refid, name, or serial number */
|
||||
if (($rcert['refid'] == $cert['refid']) ||
|
||||
($rcert['descr'] == $cert['descr']) ||
|
||||
(crl_get_entry_serial($rcert) == $serial)) {
|
||||
unset($crl['cert'][$id]);
|
||||
if (count($crl['cert']) == 0) {
|
||||
// Protect against accidentally switching the type to imported, for older CRLs
|
||||
@ -1082,6 +1108,131 @@ function cert_compare($cert1, $cert2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/****f* certs/crl_get_entry_serial
|
||||
* NAME
|
||||
* crl_get_entry_serial - Take a CRL entry and determine the associated serial
|
||||
* INPUTS
|
||||
* $entry: CRL certificate list entry to inspect, or serial string
|
||||
* RESULT
|
||||
* The requested serial string, if present, or null if it cannot be determined.
|
||||
******/
|
||||
|
||||
function crl_get_entry_serial($entry) {
|
||||
/* Check the passed entry several ways to determine the serial */
|
||||
if (isset($entry['serial']) && (strlen($entry['serial']) > 0)) {
|
||||
/* Entry is an array with a viable 'serial' element */
|
||||
return $entry['serial'];
|
||||
} elseif (isset($entry['crt'])) {
|
||||
/* Entry is an array with certificate text which can be used to
|
||||
* determine the serial */
|
||||
return cert_get_serial($entry['crt'], true);
|
||||
} elseif (cert_validate_serial($entry) != null) {
|
||||
/* Entry is a valid serial string */
|
||||
return $entry;
|
||||
}
|
||||
/* Unable to find or determine a serial number */
|
||||
return null;
|
||||
}
|
||||
|
||||
/****f* certs/cert_validate_serial
|
||||
* NAME
|
||||
* cert_validate_serial - Validate a given string to test if it can be used as
|
||||
* a certificate serial.
|
||||
* INPUTS
|
||||
* $serial : Serial number string to test
|
||||
* $returnvalue: Whether to return the parsed value or true/false
|
||||
* RESULT
|
||||
* If $returnvalue is true, then the parsed ASN.1 integer value string for
|
||||
* $serial or null if invalid
|
||||
* If $returnvalue is false, then true/false based on whether or not $serial
|
||||
* is valid.
|
||||
******/
|
||||
|
||||
function cert_validate_serial($serial, $returnvalue = false) {
|
||||
require_once('ASN1.php');
|
||||
require_once('ASN1_INT.php');
|
||||
/* The ASN.1 parsing function will throw an exception if the value is
|
||||
* invalid, so take advantage of that to catch other error as well. */
|
||||
try {
|
||||
/* If the serial is not a string, then do not bother with
|
||||
* further tests. */
|
||||
if (!is_string($serial)) {
|
||||
throw new Exception('Not a string');
|
||||
}
|
||||
/* Process a hex string */
|
||||
if ((substr($serial, 0, 2) == '0x')) {
|
||||
/* If the string is hex, then it must contain only
|
||||
* valid hex digits */
|
||||
if (!ctype_xdigit(substr($serial, 2))) {
|
||||
throw new Exception('Not a valid hex string');
|
||||
}
|
||||
/* Convert to decimal */
|
||||
$serial = base_convert($serial, 16, 10);
|
||||
}
|
||||
/* Attempt to create an ASN.1 integer, if it fails, an exception will be thrown */
|
||||
$asn1serial = new \Ukrbublik\openssl_x509_crl\ASN1_INT( $serial );
|
||||
return ($returnvalue) ? $asn1serial->content : true;
|
||||
} catch (Exception $ex) {
|
||||
/* No mattter what the error is, return null or false depending
|
||||
* on what was requested. */
|
||||
return ($returnvalue) ? null : false;
|
||||
}
|
||||
}
|
||||
|
||||
/****f* certs/crl_contains_cert
|
||||
* NAME
|
||||
* crl_contains_cert - Check if a certificate is present in a CRL
|
||||
* INPUTS
|
||||
* $crl : CRL to check
|
||||
* $cert: Certificate to test
|
||||
* RESULT
|
||||
* true if the CRL contains the certificate, false otherwise
|
||||
******/
|
||||
|
||||
function crl_contains_cert($crl, $cert) {
|
||||
global $config;
|
||||
if (!is_array($config['crl']) ||
|
||||
!is_array($crl['cert'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Find the issuer of this CRL */
|
||||
$ca = lookup_ca($crl['caref']);
|
||||
$crlissuer = is_array($cert) ? cert_get_issuer($ca['crt']) : null;
|
||||
$serial = crl_get_entry_serial($cert);
|
||||
|
||||
/* Skip issuer match when sarching by serial instead of certificate */
|
||||
$issuer = is_array($cert) ? cert_get_issuer($cert['crt']) : null;
|
||||
|
||||
/* If the requested certificate was not issued by the
|
||||
* same CA as the CRL, then do not bother checking this
|
||||
* CRL. */
|
||||
if ($issuer != $crlissuer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check CRL entries to see if the certificate serial is revoked */
|
||||
foreach ($crl['cert'] as $rcert) {
|
||||
if (crl_get_entry_serial($rcert) == $serial) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Certificate was not found in the CRL */
|
||||
return false;
|
||||
}
|
||||
|
||||
/****f* certs/is_cert_revoked
|
||||
* NAME
|
||||
* is_cert_revoked - Test if a given certificate or serial is revoked
|
||||
* INPUTS
|
||||
* $cert : Certificate entry or serial number to test
|
||||
* $crlref: CRL to check for revoked entries, or empty to check all CRLs
|
||||
* RESULT
|
||||
* true if the requested entry is revoked
|
||||
* false if the requested entry is not revoked
|
||||
******/
|
||||
|
||||
function is_cert_revoked($cert, $crlref = "") {
|
||||
global $config;
|
||||
if (!is_array($config['crl'])) {
|
||||
@ -1090,23 +1241,22 @@ function is_cert_revoked($cert, $crlref = "") {
|
||||
|
||||
if (!empty($crlref)) {
|
||||
$crl = lookup_crl($crlref);
|
||||
if (!is_array($crl['cert'])) {
|
||||
return false;
|
||||
}
|
||||
foreach ($crl['cert'] as $rcert) {
|
||||
if (cert_compare($rcert, $cert)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return crl_contains_cert($crl, $cert);
|
||||
} else {
|
||||
if (!is_array($cert)) {
|
||||
/* If passed a serial, then it cannot be definitively
|
||||
* matched in this way since we do not know the CA
|
||||
* associated with the bare serial. */
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Check every CRL in the configuration for a match */
|
||||
foreach ($config['crl'] as $crl) {
|
||||
if (!is_array($crl['cert'])) {
|
||||
continue;
|
||||
}
|
||||
foreach ($crl['cert'] as $rcert) {
|
||||
if (cert_compare($rcert, $cert)) {
|
||||
return true;
|
||||
}
|
||||
if (crl_contains_cert($crl, $cert)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,6 +102,11 @@ if ($act == "new") {
|
||||
$pconfig['caref'] = $_REQUEST['caref'];
|
||||
$pconfig['lifetime'] = $default_lifetime;
|
||||
$pconfig['serial'] = "0";
|
||||
$crlca =& lookup_ca($pconfig['caref']);
|
||||
if (!$crlca) {
|
||||
$input_errors[] = gettext('Invalid CA');
|
||||
unset($act);
|
||||
}
|
||||
}
|
||||
|
||||
if ($act == "exp") {
|
||||
@ -120,36 +125,62 @@ if ($act == "exp") {
|
||||
if ($act == "addcert") {
|
||||
unset($input_errors);
|
||||
$pconfig = $_REQUEST;
|
||||
$revoke_list = array();
|
||||
|
||||
if (!$pconfig['crlref'] || !$pconfig['certref']) {
|
||||
if (!$pconfig['crlref'] || (!$pconfig['certref'] && !$pconfig['revokeserial'])) {
|
||||
pfSenseHeader("system_crlmanager.php");
|
||||
exit;
|
||||
}
|
||||
|
||||
// certref, crlref
|
||||
$crl =& lookup_crl($pconfig['crlref']);
|
||||
$cert = lookup_cert($pconfig['certref']);
|
||||
|
||||
if (!$crl['caref'] || !$cert['caref']) {
|
||||
$input_errors[] = gettext("Both the Certificate and CRL must be specified.");
|
||||
if (!is_array($pconfig['certref'])) {
|
||||
$pconfig['certref'] = array();
|
||||
}
|
||||
|
||||
if ($crl['caref'] != $cert['caref']) {
|
||||
$input_errors[] = gettext("CA mismatch between the Certificate and CRL. Unable to Revoke.");
|
||||
if (empty($pconfig['certref']) && empty($pconfig['revokeserial'])) {
|
||||
$input_errors[] = gettext("Select one or more certificates or enter a serial number to revoke.");
|
||||
}
|
||||
if (!is_crl_internal($crl)) {
|
||||
$input_errors[] = gettext("Cannot revoke certificates for an imported/external CRL.");
|
||||
}
|
||||
|
||||
foreach ($pconfig['certref'] as $rcert) {
|
||||
$cert = lookup_cert($rcert);
|
||||
if ($crl['caref'] == $cert['caref']) {
|
||||
$revoke_list[] = $cert;
|
||||
} else {
|
||||
$input_errors[] = gettext("CA mismatch between the Certificate and CRL. Unable to Revoke.");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (explode(' ', $pconfig['revokeserial']) as $serial) {
|
||||
if (empty($serial)) {
|
||||
continue;
|
||||
}
|
||||
$vserial = cert_validate_serial($serial, true);
|
||||
if ($vserial != null) {
|
||||
$revoke_list[] = $vserial;
|
||||
} else {
|
||||
$input_errors[] = gettext("Invalid serial in list (Must be ASN.1 integer compatible decimal or hex string).");
|
||||
}
|
||||
}
|
||||
|
||||
if (!$input_errors) {
|
||||
$reason = (empty($pconfig['crlreason'])) ? 0 : $pconfig['crlreason'];
|
||||
cert_revoke($cert, $crl, $reason);
|
||||
|
||||
foreach ($revoke_list as $cert) {
|
||||
cert_revoke($cert, $crl, $reason);
|
||||
}
|
||||
|
||||
// refresh IPsec and OpenVPN CRLs
|
||||
openvpn_refresh_crls();
|
||||
vpn_ipsec_configure();
|
||||
write_config("Revoked cert {$cert['descr']} in CRL {$crl['descr']}.");
|
||||
write_config("Revoked certificate(s) in CRL {$crl['descr']}.");
|
||||
pfSenseHeader("system_crlmanager.php");
|
||||
exit;
|
||||
} else {
|
||||
$act = 'edit';
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,13 +316,13 @@ function method_change() {
|
||||
|
||||
<?php
|
||||
|
||||
function build_method_list() {
|
||||
function build_method_list($importonly = false) {
|
||||
global $_POST, $crl_methods;
|
||||
|
||||
$list = array();
|
||||
|
||||
foreach ($crl_methods as $method => $desc) {
|
||||
if (($_POST['importonly'] == "yes") && ($method != "existing")) {
|
||||
if ($importonly && ($method != "existing")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -339,17 +370,22 @@ $tab_array[] = array(gettext("Certificates"), false, "system_certmanager.php");
|
||||
$tab_array[] = array(gettext("Certificate Revocation"), true, "system_crlmanager.php");
|
||||
display_top_tabs($tab_array);
|
||||
|
||||
if ($act == "new" || $act == gettext("Save") || $input_errors) {
|
||||
if ($act == "new" || $act == gettext("Save")) {
|
||||
$form = new Form();
|
||||
|
||||
$section = new Form_Section('Create new Revocation List');
|
||||
|
||||
$section->addInput(new Form_StaticText(
|
||||
'Certificate Authority',
|
||||
$crlca['descr'],
|
||||
));
|
||||
|
||||
if (!isset($id)) {
|
||||
$section->addInput(new Form_Select(
|
||||
'method',
|
||||
'*Method',
|
||||
$pconfig['method'],
|
||||
build_method_list()
|
||||
build_method_list((!isset($crlca['prv']) || empty($crlca['prv'])))
|
||||
));
|
||||
}
|
||||
|
||||
@ -360,11 +396,11 @@ if ($act == "new" || $act == gettext("Save") || $input_errors) {
|
||||
$pconfig['descr']
|
||||
));
|
||||
|
||||
$section->addInput(new Form_Select(
|
||||
$form->addGlobal(new Form_Input(
|
||||
'caref',
|
||||
'*Certificate Authority',
|
||||
$pconfig['caref'],
|
||||
build_ca_list()
|
||||
null,
|
||||
'hidden',
|
||||
$pconfig['caref']
|
||||
));
|
||||
|
||||
$form->add($section);
|
||||
@ -463,9 +499,10 @@ if ($act == "new" || $act == gettext("Save") || $input_errors) {
|
||||
print_info_box(gettext("No certificates found for this CRL."), 'danger');
|
||||
} else {
|
||||
?>
|
||||
<table class="table table-striped table-hover table-condensed">
|
||||
<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap" data-sortable>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?=gettext("Serial")?></th>
|
||||
<th><?=gettext("Certificate Name")?></th>
|
||||
<th><?=gettext("Revocation Reason")?></th>
|
||||
<th><?=gettext("Revoked At")?></th>
|
||||
@ -475,18 +512,16 @@ if ($act == "new" || $act == gettext("Save") || $input_errors) {
|
||||
<tbody>
|
||||
<?php
|
||||
foreach ($crl['cert'] as $i => $cert):
|
||||
$name = htmlspecialchars($cert['descr']);
|
||||
?>
|
||||
$name = empty($cert['descr']) ? gettext('Revoked by Serial') : htmlspecialchars($cert['descr']);
|
||||
$serial = crl_get_entry_serial($cert);
|
||||
if (empty($serial)) {
|
||||
$serial = gettext("Invalid");
|
||||
} ?>
|
||||
<tr>
|
||||
<td class="listlr">
|
||||
<?=$name; ?>
|
||||
</td>
|
||||
<td class="listlr">
|
||||
<?=$openssl_crl_status[$cert["reason"]]; ?>
|
||||
</td>
|
||||
<td class="listlr">
|
||||
<?=date("D M j G:i:s T Y", $cert["revoke_time"]); ?>
|
||||
</td>
|
||||
<td><?=htmlspecialchars($serial);?></td>
|
||||
<td><?=$name; ?></td>
|
||||
<td><?=$openssl_crl_status[$cert['reason']]; ?></td>
|
||||
<td><?=date("D M j G:i:s T Y", $cert['revoke_time']); ?></td>
|
||||
<td class="list">
|
||||
<a href="system_crlmanager.php?act=delcert&id=<?=$crl['refid']; ?>&certref=<?=$cert['refid']; ?>" usepost>
|
||||
<i class="fa fa-trash" title="<?=gettext("Delete this certificate from the CRL")?>" alt="<?=gettext("Delete this certificate from the CRL")?>"></i>
|
||||
@ -516,31 +551,39 @@ if ($act == "new" || $act == gettext("Save") || $input_errors) {
|
||||
print_info_box(gettext("No certificates found for this CA."), 'danger');
|
||||
} else {
|
||||
$section = new Form_Section('Choose a Certificate to Revoke');
|
||||
$group = new Form_Group(null);
|
||||
|
||||
$group->add(new Form_Select(
|
||||
'certref',
|
||||
null,
|
||||
$pconfig['certref'],
|
||||
build_cacert_list()
|
||||
))->setWidth(4)->setHelp('Certificate');
|
||||
|
||||
$group->add(new Form_Select(
|
||||
$section->addInput(new Form_Select(
|
||||
'crlreason',
|
||||
null,
|
||||
'Reason',
|
||||
-1,
|
||||
$openssl_crl_status
|
||||
))->setHelp('Reason');
|
||||
))->setHelp('Select the reason for which the certificates are being revoked.');
|
||||
|
||||
$group->add(new Form_Button(
|
||||
$cacert_list = build_cacert_list();
|
||||
|
||||
$section->addInput(new Form_Select(
|
||||
'certref',
|
||||
'Revoke Certificates',
|
||||
$pconfig['certref'],
|
||||
$cacert_list,
|
||||
true
|
||||
))->addClass('multiselect')
|
||||
->setHelp('Hold down CTRL (PC)/COMMAND (Mac) key to select multiple items.');
|
||||
|
||||
$section->addInput(new Form_Input(
|
||||
'revokeserial',
|
||||
'Revoke by Serial',
|
||||
'text',
|
||||
$pconfig['revokeserial']
|
||||
))->setHelp('List of certificate serial numbers to revoke (separated by spaces)');
|
||||
|
||||
$form->addGlobal(new Form_Button(
|
||||
'submit',
|
||||
'Add',
|
||||
null,
|
||||
'fa-plus'
|
||||
))->addClass('btn-success btn-sm');
|
||||
|
||||
$section->add($group);
|
||||
|
||||
$form->addGlobal(new Form_Input(
|
||||
'id',
|
||||
null,
|
||||
@ -570,11 +613,12 @@ if ($act == "new" || $act == gettext("Save") || $input_errors) {
|
||||
?>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading"><h2 class="panel-title"><?=gettext("Additional Certificate Revocation Lists")?></h2></div>
|
||||
<div class="panel-heading"><h2 class="panel-title"><?=gettext("Certificate Revocation Lists")?></h2></div>
|
||||
<div class="panel-body table-responsive">
|
||||
<table class="table table-striped table-hover table-condensed table-rowdblclickedit">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?=gettext("CA")?></th>
|
||||
<th><?=gettext("Name")?></th>
|
||||
<th><?=gettext("Internal")?></th>
|
||||
<th><?=gettext("Certificates")?></th>
|
||||
@ -596,39 +640,7 @@ if ($act == "new" || $act == gettext("Save") || $input_errors) {
|
||||
|
||||
$i = 0;
|
||||
foreach ($a_ca as $ca):
|
||||
$name = htmlspecialchars($ca['descr']);
|
||||
|
||||
if ($ca['prv']) {
|
||||
$cainternal = "YES";
|
||||
} else {
|
||||
$cainternal = "NO";
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
<?=$name?>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
if ($cainternal == "YES"):
|
||||
?>
|
||||
<a href="system_crlmanager.php?act=new&caref=<?=$ca['refid']; ?>" class="btn btn-xs btn-success">
|
||||
<i class="fa fa-plus icon-embed-btn"></i>
|
||||
<?=gettext("Add or Import CRL")?>
|
||||
</a>
|
||||
<?php
|
||||
else:
|
||||
?>
|
||||
<a href="system_crlmanager.php?act=new&caref=<?=$ca['refid']; ?>&importonly=yes" class="btn btn-xs btn-success">
|
||||
<i class="fa fa-plus icon-embed-btn"></i>
|
||||
<?=gettext("Add or Import CRL")?>
|
||||
</a>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
$caname = htmlspecialchars($ca['descr']);
|
||||
if (is_array($ca_crl_map[$ca['refid']])):
|
||||
foreach ($ca_crl_map[$ca['refid']] as $crl):
|
||||
$tmpcrl = lookup_crl($crl);
|
||||
@ -639,6 +651,7 @@ if ($act == "new" || $act == gettext("Save") || $input_errors) {
|
||||
$inuse = crl_in_use($tmpcrl['refid']);
|
||||
?>
|
||||
<tr>
|
||||
<td><?=$caname?></td>
|
||||
<td><?=$tmpcrl['descr']; ?></td>
|
||||
<td><i class="fa fa-<?=($internal) ? "check" : "times"; ?>"></i></td>
|
||||
<td><?=($internal) ? count($tmpcrl['cert']) : "Unknown (imported)"; ?></td>
|
||||
@ -675,9 +688,33 @@ if ($act == "new" || $act == gettext("Save") || $input_errors) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<?php
|
||||
$form = new Form(false);
|
||||
$section = new Form_Section('Create or Import a New Certificate Revocation List');
|
||||
$group = new Form_Group(null);
|
||||
$group->add(new Form_Select(
|
||||
'caref',
|
||||
'Certificate Authority',
|
||||
null,
|
||||
build_ca_list()
|
||||
))->setHelp('Select a Certificate Authority for the new CRL');
|
||||
$group->add(new Form_Button(
|
||||
'submit',
|
||||
'Add',
|
||||
null,
|
||||
'fa-plus'
|
||||
))->addClass('btn-success btn-sm');
|
||||
$section->add($group);
|
||||
$form->addGlobal(new Form_Input(
|
||||
'act',
|
||||
null,
|
||||
'hidden',
|
||||
'new'
|
||||
));
|
||||
$form->add($section);
|
||||
print($form);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<script type="text/javascript">
|
||||
@ -701,6 +738,7 @@ events.push(function() {
|
||||
|
||||
hideClass('internal', ($('#method').val() == 'existing'));
|
||||
hideClass('existing', ($('#method').val() == 'internal'));
|
||||
$('.multiselect').attr("size","<?= max(3, min(15, count($cacert_list))) ?>");
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user