Project

General

Profile

Download (18.2 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
 * system_crlmanager.php
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8
 * Copyright (c) 2014-2019 Rubicon Communications, LLC (Netgate)
9
 * All rights reserved.
10
 *
11
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14
 *
15
 * http://www.apache.org/licenses/LICENSE-2.0
16
 *
17
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22
 */
23

    
24
##|+PRIV
25
##|*IDENT=page-system-crlmanager
26
##|*NAME=System: CRL Manager
27
##|*DESCR=Allow access to the 'System: CRL Manager' page.
28
##|*MATCH=system_crlmanager.php*
29
##|-PRIV
30

    
31
require_once("guiconfig.inc");
32
require_once("certs.inc");
33
require_once("openvpn.inc");
34
require_once("pfsense-utils.inc");
35
require_once("vpn.inc");
36

    
37
$max_lifetime = cert_get_max_lifetime();
38
$default_lifetime = min(9999, $max_lifetime);
39

    
40
global $openssl_crl_status;
41

    
42
$crl_methods = array(
43
	"internal" => gettext("Create an internal Certificate Revocation List"),
44
	"existing" => gettext("Import an existing Certificate Revocation List"));
45

    
46
if (isset($_REQUEST['id']) && ctype_alnum($_REQUEST['id'])) {
47
	$id = $_REQUEST['id'];
48
}
49

    
50
init_config_arr(array('ca'));
51
$a_ca = &$config['ca'];
52

    
53
init_config_arr(array('cert'));
54
$a_cert = &$config['cert'];
55

    
56
init_config_arr(array('crl'));
57
$a_crl = &$config['crl'];
58

    
59
/* Clean up blank entries missing a reference ID */
60
foreach ($a_crl as $cid => $acrl) {
61
	if (!isset($acrl['refid'])) {
62
		unset ($a_crl[$cid]);
63
	}
64
}
65

    
66
$act = $_REQUEST['act'];
67

    
68
$cacert_list = array();
69

    
70
if (!empty($id)) {
71
	$thiscrl =& lookup_crl($id);
72
}
73

    
74
/* Actions other than 'new' require a CRL to act upon.
75
 * 'del' action must be submitted via POST. */
76
if ((!empty($act) &&
77
    ($act != 'new') &&
78
    !$thiscrl) ||
79
    (($act == 'del') && empty($_POST))) {
80
	pfSenseHeader("system_camanager.php");
81
	$act="";
82
	$savemsg = gettext("Invalid CRL reference.");
83
	$class = "danger";
84
}
85

    
86
switch ($act) {
87
	case 'del':
88
		$name = htmlspecialchars($thiscrl['descr']);
89
		if (crl_in_use($id)) {
90
			$savemsg = sprintf(gettext("Certificate Revocation List %s is in use and cannot be deleted."), $name);
91
			$class = "danger";
92
		} else {
93
			foreach ($a_crl as $cid => $acrl) {
94
				if ($acrl['refid'] == $thiscrl['refid']) {
95
					unset($a_crl[$cid]);
96
				}
97
			}
98
			write_config("Deleted CRL {$name}.");
99
			$savemsg = sprintf(gettext("Certificate Revocation List %s successfully deleted."), $name);
100
			$class = "success";
101
		}
102
		break;
103
	case 'new':
104
		$pconfig['method'] = $_REQUEST['method'];
105
		$pconfig['caref'] = $_REQUEST['caref'];
106
		$pconfig['lifetime'] = $default_lifetime;
107
		$pconfig['serial'] = "0";
108
		$crlca =& lookup_ca($pconfig['caref']);
109
		if (!$crlca) {
110
			$input_errors[] = gettext('Invalid CA');
111
			unset($act);
112
		}
113
		break;
114
	case 'addcert':
115
		unset($input_errors);
116
		$pconfig = $_REQUEST;
117
		$revoke_list = array();
118
		if (!$pconfig['crlref'] || (!$pconfig['certref'] && !$pconfig['revokeserial'])) {
119
			pfSenseHeader("system_crlmanager.php");
120
			exit;
121
		}
122
		$crl =& lookup_crl($pconfig['crlref']);
123
		if (!is_array($pconfig['certref'])) {
124
			$pconfig['certref'] = array();
125
		}
126
		if (empty($pconfig['certref']) && empty($pconfig['revokeserial'])) {
127
			$input_errors[] = gettext("Select one or more certificates or enter a serial number to revoke.");
128
		}
129
		if (!is_crl_internal($crl)) {
130
			$input_errors[] = gettext("Cannot revoke certificates for an imported/external CRL.");
131
		}
132
		foreach ($pconfig['certref'] as $rcert) {
133
			$cert = lookup_cert($rcert);
134
			if ($crl['caref'] == $cert['caref']) {
135
				$revoke_list[] = $cert;
136
			} else {
137
				$input_errors[] = gettext("CA mismatch between the Certificate and CRL. Unable to Revoke.");
138
			}
139
		}
140
		foreach (explode(' ', $pconfig['revokeserial']) as $serial) {
141
			if (empty($serial)) {
142
				continue;
143
			}
144
			$vserial = cert_validate_serial($serial, true, true);
145
			if ($vserial != null) {
146
				$revoke_list[] = $vserial;
147
			} else {
148
				$input_errors[] = gettext("Invalid serial in list (Must be ASN.1 integer compatible decimal or hex string).");
149
			}
150
		}
151
		if (!$input_errors) {
152
			$reason = (empty($pconfig['crlreason'])) ? 0 : $pconfig['crlreason'];
153
			foreach ($revoke_list as $cert) {
154
				cert_revoke($cert, $crl, $reason);
155
			}
156
			// refresh IPsec and OpenVPN CRLs
157
			openvpn_refresh_crls();
158
			vpn_ipsec_configure();
159
			write_config("Revoked certificate(s) in CRL {$crl['descr']}.");
160
			pfSenseHeader("system_crlmanager.php");
161
			exit;
162
		} else {
163
			$act = 'edit';
164
		}
165
		break;
166
	case 'delcert':
167
		if (!is_array($thiscrl['cert'])) {
168
			pfSenseHeader("system_crlmanager.php");
169
			exit;
170
		}
171
		$found = false;
172
		foreach ($thiscrl['cert'] as $acert) {
173
			if ($acert['refid'] == $_REQUEST['certref']) {
174
				$found = true;
175
				$thiscert = $acert;
176
			}
177
		}
178
		if (!$found) {
179
			pfSenseHeader("system_crlmanager.php");
180
			exit;
181
		}
182
		$certname = htmlspecialchars($thiscert['descr']);
183
		$crlname = htmlspecialchars($thiscrl['descr']);
184
		if (cert_unrevoke($thiscert, $thiscrl)) {
185
			$savemsg = sprintf(gettext('Deleted Certificate %1$s from CRL %2$s.'), $certname, $crlname);
186
			$class = "success";
187
			// refresh IPsec and OpenVPN CRLs
188
			openvpn_refresh_crls();
189
			vpn_ipsec_configure();
190
			write_config($savemsg);
191
		} else {
192
			$savemsg = sprintf(gettext('Failed to delete Certificate %1$s from CRL %2$s.'), $certname, $crlname);
193
			$class = "danger";
194
		}
195
		$act="edit";
196
		break;
197
	case 'exp':
198
		/* Exporting the CRL contents*/
199
		crl_update($thiscrl);
200
		send_user_download('data', base64_decode($thiscrl['text']), "{$thiscrl['descr']}.crl");
201
		break;
202
	default:
203
		break;
204
}
205

    
206
if ($_POST['save']) {
207
	$input_errors = array();
208
	$pconfig = $_POST;
209

    
210
	/* input validation */
211
	if (($pconfig['method'] == "existing") || ($act == "editimported")) {
212
		$reqdfields = explode(" ", "descr crltext");
213
		$reqdfieldsn = array(
214
			gettext("Descriptive name"),
215
			gettext("Certificate Revocation List data"));
216
	}
217
	if ($pconfig['method'] == "internal") {
218
		$reqdfields = explode(" ", "descr caref");
219
		$reqdfieldsn = array(
220
			gettext("Descriptive name"),
221
			gettext("Certificate Authority"));
222
	}
223

    
224
	do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
225

    
226
	if (preg_match("/[\?\>\<\&\/\\\"\']/", $pconfig['descr'])) {
227
		array_push($input_errors, "The field 'Descriptive Name' contains invalid characters.");
228
	}
229
	if ($pconfig['lifetime'] > $max_lifetime) {
230
		$input_errors[] = gettext("Lifetime is longer than the maximum allowed value. Use a shorter lifetime.");
231
	}
232

    
233
	if (!empty($pconfig['serial']) && !cert_validate_serial($pconfig['serial'])) {
234
		$input_errors[] = gettext("Please enter a valid integer serial number.");
235
	}
236

    
237
	/* save modifications */
238
	if (!$input_errors) {
239
		$result = false;
240

    
241
		if ($thiscrl) {
242
			$crl =& $thiscrl;
243
		} else {
244
			$crl = array();
245
			$crl['refid'] = uniqid();
246
		}
247

    
248
		$crl['descr'] = $pconfig['descr'];
249
		if ($act != "editimported") {
250
			$crl['caref'] = $pconfig['caref'];
251
			$crl['method'] = $pconfig['method'];
252
		}
253

    
254
		if (($pconfig['method'] == "existing") || ($act == "editimported")) {
255
			$crl['text'] = base64_encode($pconfig['crltext']);
256
		}
257

    
258
		if ($pconfig['method'] == "internal") {
259
			$crl['serial'] = empty($pconfig['serial']) ? 9999 : $pconfig['serial'];
260
			$crl['lifetime'] = empty($pconfig['lifetime']) ? $default_lifetime : $pconfig['lifetime'];
261
			$crl['cert'] = array();
262
		}
263

    
264
		if (!$thiscrl) {
265
			$a_crl[] = $crl;
266
		}
267

    
268
		write_config("Saved CRL {$crl['descr']}");
269
		// refresh IPsec and OpenVPN CRLs
270
		openvpn_refresh_crls();
271
		vpn_ipsec_configure();
272
		pfSenseHeader("system_crlmanager.php");
273
	}
274
}
275

    
276
$pgtitle = array(gettext("System"), gettext("Certificate Manager"), gettext("Certificate Revocation"));
277
$pglinks = array("", "system_camanager.php", "system_crlmanager.php");
278

    
279
if ($act == "new" || $act == gettext("Save") || $input_errors || $act == "edit") {
280
	$pgtitle[] = gettext('Edit');
281
	$pglinks[] = "@self";
282
}
283
include("head.inc");
284
?>
285

    
286
<script type="text/javascript">
287
//<![CDATA[
288

    
289
function method_change() {
290

    
291
	method = document.iform.method.value;
292

    
293
	switch (method) {
294
		case "internal":
295
			document.getElementById("existing").style.display="none";
296
			document.getElementById("internal").style.display="";
297
			break;
298
		case "existing":
299
			document.getElementById("existing").style.display="";
300
			document.getElementById("internal").style.display="none";
301
			break;
302
	}
303
}
304

    
305
//]]>
306
</script>
307

    
308
<?php
309

    
310
function build_method_list($importonly = false) {
311
	global $_POST, $crl_methods;
312

    
313
	$list = array();
314

    
315
	foreach ($crl_methods as $method => $desc) {
316
		if ($importonly && ($method != "existing")) {
317
			continue;
318
		}
319

    
320
		$list[$method] = $desc;
321
	}
322

    
323
	return($list);
324
}
325

    
326
function build_ca_list() {
327
	global $a_ca;
328

    
329
	$list = array();
330

    
331
	foreach ($a_ca as $ca) {
332
		$list[$ca['refid']] = $ca['descr'];
333
	}
334

    
335
	return($list);
336
}
337

    
338
function build_cacert_list() {
339
	global $a_cert, $crl, $id;
340

    
341
	$list = array();
342
	foreach ($a_cert as $cert) {
343
		if ((isset($cert['caref']) && !empty($cert['caref'])) &&
344
		    ($cert['caref'] == $crl['caref']) &&
345
		    !is_cert_revoked($cert, $id)) {
346
			$list[$cert['refid']] = $cert['descr'];
347
		}
348
	}
349

    
350
	return($list);
351
}
352

    
353
if ($input_errors) {
354
	print_input_errors($input_errors);
355
}
356

    
357
if ($savemsg) {
358
	print_info_box($savemsg, $class);
359
}
360

    
361
$tab_array = array();
362
$tab_array[] = array(gettext("CAs"), false, "system_camanager.php");
363
$tab_array[] = array(gettext("Certificates"), false, "system_certmanager.php");
364
$tab_array[] = array(gettext("Certificate Revocation"), true, "system_crlmanager.php");
365
display_top_tabs($tab_array);
366

    
367
if ($act == "new" || $act == gettext("Save")) {
368
	$form = new Form();
369

    
370
	$section = new Form_Section('Create new Revocation List');
371

    
372
	$section->addInput(new Form_StaticText(
373
		'Certificate Authority',
374
		$crlca['descr'],
375
	));
376

    
377
	if (!isset($id)) {
378
		$section->addInput(new Form_Select(
379
			'method',
380
			'*Method',
381
			$pconfig['method'],
382
			build_method_list((!isset($crlca['prv']) || empty($crlca['prv'])))
383
		));
384
	}
385

    
386
	$section->addInput(new Form_Input(
387
		'descr',
388
		'*Descriptive name',
389
		'text',
390
		$pconfig['descr']
391
	));
392

    
393
	$form->addGlobal(new Form_Input(
394
		'caref',
395
		null,
396
		'hidden',
397
		$pconfig['caref']
398
	));
399

    
400
	$form->add($section);
401

    
402
	$section = new Form_Section('Existing Certificate Revocation List');
403
	$section->addClass('existing');
404

    
405
	$section->addInput(new Form_Textarea(
406
		'crltext',
407
		'*CRL data',
408
		$pconfig['crltext']
409
		))->setHelp('Paste a Certificate Revocation List in X.509 CRL format here.');
410

    
411
	$form->add($section);
412

    
413
	$section = new Form_Section('Internal Certificate Revocation List');
414
	$section->addClass('internal');
415

    
416
	$section->addInput(new Form_Input(
417
		'lifetime',
418
		'Lifetime (Days)',
419
		'number',
420
		$pconfig['lifetime'],
421
		['max' => $max_lifetime]
422
	));
423

    
424
	$section->addInput(new Form_Input(
425
		'serial',
426
		'Serial',
427
		'number',
428
		$pconfig['serial'],
429
		['min' => '0']
430
	));
431

    
432
	$form->add($section);
433

    
434
	if (isset($id) && $thiscrl) {
435
		$form->addGlobal(new Form_Input(
436
			'id',
437
			null,
438
			'hidden',
439
			$id
440
		));
441
	}
442

    
443
	print($form);
444

    
445
} elseif ($act == "editimported") {
446

    
447
	$form = new Form();
448

    
449
	$section = new Form_Section('Edit Imported Certificate Revocation List');
450

    
451
	$section->addInput(new Form_Input(
452
		'descr',
453
		'*Descriptive name',
454
		'text',
455
		$pconfig['descr']
456
	));
457

    
458
	$section->addInput(new Form_Textarea(
459
		'crltext',
460
		'*CRL data',
461
		$pconfig['crltext']
462
	))->setHelp('Paste a Certificate Revocation List in X.509 CRL format here.');
463

    
464
	$form->addGlobal(new Form_Input(
465
		'id',
466
		null,
467
		'hidden',
468
		$id
469
	));
470

    
471
	$form->addGlobal(new Form_Input(
472
		'act',
473
		null,
474
		'hidden',
475
		'editimported'
476
	));
477

    
478
	$form->add($section);
479

    
480
	print($form);
481

    
482
} elseif ($act == "edit") {
483
	$crl = $thiscrl;
484

    
485
	$form = new Form(false);
486
?>
487

    
488
	<div class="panel panel-default">
489
		<div class="panel-heading"><h2 class="panel-title"><?=gettext("Revoked Certificates in CRL") . ': ' . $crl['descr']?></h2></div>
490
		<div class="panel-body table-responsive">
491
<?php
492
	if (!is_array($crl['cert']) || (count($crl['cert']) == 0)) {
493
		print_info_box(gettext("No certificates found for this CRL."), 'danger');
494
	} else {
495
?>
496
			<table class="table table-striped table-hover table-condensed sortable-theme-bootstrap" data-sortable>
497
				<thead>
498
					<tr>
499
						<th><?=gettext("Serial")?></th>
500
						<th><?=gettext("Certificate Name")?></th>
501
						<th><?=gettext("Revocation Reason")?></th>
502
						<th><?=gettext("Revoked At")?></th>
503
						<th></th>
504
					</tr>
505
				</thead>
506
				<tbody>
507
<?php
508
		foreach ($crl['cert'] as $i => $cert):
509
			$name = empty($cert['descr']) ? gettext('Revoked by Serial') : htmlspecialchars($cert['descr']);
510
			$serial = crl_get_entry_serial($cert);
511
			if (empty($serial)) {
512
				$serial = gettext("Invalid");
513
			} ?>
514
					<tr>
515
						<td><?=htmlspecialchars($serial);?></td>
516
						<td><?=$name; ?></td>
517
						<td><?=$openssl_crl_status[$cert['reason']]; ?></td>
518
						<td><?=date("D M j G:i:s T Y", $cert['revoke_time']); ?></td>
519
						<td class="list">
520
							<a href="system_crlmanager.php?act=delcert&amp;id=<?=$crl['refid']; ?>&amp;certref=<?=$cert['refid']; ?>" usepost>
521
								<i class="fa fa-trash" title="<?=gettext("Delete this certificate from the CRL")?>" alt="<?=gettext("Delete this certificate from the CRL")?>"></i>
522
							</a>
523
						</td>
524
					</tr>
525
<?php
526
		endforeach;
527
?>
528
				</tbody>
529
			</table>
530
<?php
531
	}
532
?>
533
		</div>
534
	</div>
535
<?php
536

    
537
	$section = new Form_Section('Revoke Certificates');
538

    
539
	$section->addInput(new Form_Select(
540
		'crlreason',
541
		'Reason',
542
		-1,
543
		$openssl_crl_status
544
		))->setHelp('Select the reason for which the certificates are being revoked.');
545

    
546
	$cacert_list = build_cacert_list();
547
	if (count($cacert_list) == 0) {
548
		print_info_box(gettext("No certificates found for this CA."), 'danger');
549
	} else {
550
		$section->addInput(new Form_Select(
551
			'certref',
552
			'Revoke Certificates',
553
			$pconfig['certref'],
554
			$cacert_list,
555
			true
556
			))->addClass('multiselect')
557
			->setHelp('Hold down CTRL (PC)/COMMAND (Mac) key to select multiple items.');
558
	}
559

    
560
	$section->addInput(new Form_Input(
561
		'revokeserial',
562
		'Revoke by Serial',
563
		'text',
564
		$pconfig['revokeserial']
565
	))->setHelp('List of certificate serial numbers to revoke (separated by spaces)');
566

    
567
	$form->addGlobal(new Form_Button(
568
		'submit',
569
		'Add',
570
		null,
571
		'fa-plus'
572
		))->addClass('btn-success btn-sm');
573

    
574
	$form->addGlobal(new Form_Input(
575
		'id',
576
		null,
577
		'hidden',
578
		$crl['refid']
579
	));
580

    
581
	$form->addGlobal(new Form_Input(
582
		'act',
583
		null,
584
		'hidden',
585
		'addcert'
586
	));
587

    
588
	$form->addGlobal(new Form_Input(
589
		'crlref',
590
		null,
591
		'hidden',
592
		$crl['refid']
593
	));
594

    
595
	$form->add($section);
596

    
597
	print($form);
598
} else {
599
?>
600

    
601
	<div class="panel panel-default">
602
		<div class="panel-heading"><h2 class="panel-title"><?=gettext("Certificate Revocation Lists")?></h2></div>
603
		<div class="panel-body table-responsive">
604
			<table class="table table-striped table-hover table-condensed table-rowdblclickedit">
605
				<thead>
606
					<tr>
607
						<th><?=gettext("CA")?></th>
608
						<th><?=gettext("Name")?></th>
609
						<th><?=gettext("Internal")?></th>
610
						<th><?=gettext("Certificates")?></th>
611
						<th><?=gettext("In Use")?></th>
612
						<th><?=gettext("Actions")?></th>
613
					</tr>
614
				</thead>
615
				<tbody>
616
<?php
617
	$pluginparams = array();
618
	$pluginparams['type'] = 'certificates';
619
	$pluginparams['event'] = 'used_crl';
620
	$certificates_used_by_packages = pkg_call_plugins('plugin_certificates', $pluginparams);
621
	// Map CRLs to CAs in one pass
622
	$ca_crl_map = array();
623
	foreach ($a_crl as $crl) {
624
		$ca_crl_map[$crl['caref']][] = $crl['refid'];
625
	}
626

    
627
	$i = 0;
628
	foreach ($a_ca as $ca):
629
		$caname = htmlspecialchars($ca['descr']);
630
		if (is_array($ca_crl_map[$ca['refid']])):
631
			foreach ($ca_crl_map[$ca['refid']] as $crl):
632
				$tmpcrl = lookup_crl($crl);
633
				$internal = is_crl_internal($tmpcrl);
634
				if ($internal && (!isset($tmpcrl['cert']) || empty($tmpcrl['cert'])) ) {
635
					$tmpcrl['cert'] = array();
636
				}
637
				$inuse = crl_in_use($tmpcrl['refid']);
638
?>
639
					<tr>
640
						<td><?=$caname?></td>
641
						<td><?=$tmpcrl['descr']; ?></td>
642
						<td><i class="fa fa-<?=($internal) ? "check" : "times"; ?>"></i></td>
643
						<td><?=($internal) ? count($tmpcrl['cert']) : "Unknown (imported)"; ?></td>
644
						<td><i class="fa fa-<?=($inuse) ? "check" : "times"; ?>"></i>
645
						<?php echo cert_usedby_description($tmpcrl['refid'], $certificates_used_by_packages); ?>
646
						</td>
647
						<td>
648
							<a href="system_crlmanager.php?act=exp&amp;id=<?=$tmpcrl['refid']?>" class="fa fa-download" title="<?=gettext("Export CRL")?>" ></a>
649
<?php
650
				if ($internal): ?>
651
							<a href="system_crlmanager.php?act=edit&amp;id=<?=$tmpcrl['refid']?>" class="fa fa-pencil" title="<?=gettext("Edit CRL")?>"></a>
652
<?php
653
				else:
654
?>
655
							<a href="system_crlmanager.php?act=editimported&amp;id=<?=$tmpcrl['refid']?>" class="fa fa-pencil" title="<?=gettext("Edit CRL")?>"></a>
656
<?php			endif;
657
				if (!$inuse):
658
?>
659
							<a href="system_crlmanager.php?act=del&amp;id=<?=$tmpcrl['refid']?>" class="fa fa-trash" title="<?=gettext("Delete CRL")?>" usepost></a>
660
<?php
661
				endif;
662
?>
663
						</td>
664
					</tr>
665
<?php
666
				$i++;
667
				endforeach;
668
			endif;
669
			$i++;
670
		endforeach;
671
?>
672
				</tbody>
673
			</table>
674
		</div>
675
	</div>
676

    
677
<?php
678
	$form = new Form(false);
679
	$section = new Form_Section('Create or Import a New Certificate Revocation List');
680
	$group = new Form_Group(null);
681
	$group->add(new Form_Select(
682
		'caref',
683
		'Certificate Authority',
684
		null,
685
		build_ca_list()
686
		))->setHelp('Select a Certificate Authority for the new CRL');
687
	$group->add(new Form_Button(
688
		'submit',
689
		'Add',
690
		null,
691
		'fa-plus'
692
		))->addClass('btn-success btn-sm');
693
	$section->add($group);
694
	$form->addGlobal(new Form_Input(
695
		'act',
696
		null,
697
		'hidden',
698
		'new'
699
	));
700
	$form->add($section);
701
	print($form);
702
}
703

    
704
?>
705

    
706
<script type="text/javascript">
707
//<![CDATA[
708
events.push(function() {
709

    
710
	// Hides all elements of the specified class. This will usually be a section or group
711
	function hideClass(s_class, hide) {
712
		if (hide) {
713
			$('.' + s_class).hide();
714
		} else {
715
			$('.' + s_class).show();
716
		}
717
	}
718

    
719
	// When the 'method" selector is changed, we show/hide certain sections
720
	$('#method').on('change', function() {
721
		hideClass('internal', ($('#method').val() == 'existing'));
722
		hideClass('existing', ($('#method').val() == 'internal'));
723
	});
724

    
725
	hideClass('internal', ($('#method').val() == 'existing'));
726
	hideClass('existing', ($('#method').val() == 'internal'));
727
	$('.multiselect').attr("size","<?= max(3, min(15, count($cacert_list))) ?>");
728
});
729
//]]>
730
</script>
731

    
732
<?php include("foot.inc");
(195-195/227)