summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xinstall/static/certificate.js317
-rw-r--r--install/static/host.js41
-rw-r--r--install/static/ipa.css19
-rw-r--r--install/static/service.js290
-rw-r--r--install/static/test/all_tests.html4
-rw-r--r--install/static/test/association_tests.html2
-rwxr-xr-xinstall/static/test/certificate_tests.html24
-rwxr-xr-xinstall/static/test/certificate_tests.js79
-rw-r--r--install/static/test/data/cert_show.json1
-rw-r--r--install/static/test/data/host_show.json14
-rw-r--r--install/static/test/details_tests.html2
-rw-r--r--install/static/test/entity_tests.html2
-rw-r--r--install/static/test/index.html1
-rw-r--r--install/static/test/ipa_tests.html2
-rw-r--r--install/static/test/navigation_tests.html2
-rw-r--r--ipalib/plugins/host.py35
16 files changed, 549 insertions, 286 deletions
diff --git a/install/static/certificate.js b/install/static/certificate.js
index a688fe81..e1297a83 100755
--- a/install/static/certificate.js
+++ b/install/static/certificate.js
@@ -18,6 +18,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+var BEGIN_CERTIFICATE = '-----BEGIN CERTIFICATE-----';
+var END_CERTIFICATE = '-----END CERTIFICATE-----';
+
var BEGIN_CERTIFICATE_REQUEST = '-----BEGIN CERTIFICATE REQUEST-----';
var END_CERTIFICATE_REQUEST = '-----END CERTIFICATE REQUEST-----';
@@ -35,19 +38,33 @@ var CRL_REASON = [
'AA Compromise'
];
+var CERTIFICATE_STATUS_MISSING = 0;
+var CERTIFICATE_STATUS_VALID = 1;
+var CERTIFICATE_STATUS_REVOKED = 2;
+
function certificate_parse_dn(dn) {
var result = {};
+ if (!dn) return result;
// TODO: Use proper LDAP DN parser
var rdns = dn.split(',');
for (var i=0; i<rdns.length; i++) {
var rdn = rdns[i];
- var parts = rdn.split('=');
- var name = parts[0].toLowerCase();
- var value = parts[1];
+ if (!rdn) continue;
- result[name] = value;
+ var parts = rdn.split('=');
+ var name = $.trim(parts[0].toLowerCase());
+ var value = $.trim(parts[1]);
+
+ var old_value = result[name];
+ if (!old_value) {
+ result[name] = value;
+ } else if (typeof old_value == "string") {
+ result[name] = [old_value, value];
+ } else {
+ result[name].push(value);
+ }
}
return result;
@@ -70,9 +87,9 @@ function certificate_get_dialog(spec) {
}).appendTo(dialog);
textarea.val(
- BEGIN_CERTIFICATE_REQUEST+'\n'+
+ BEGIN_CERTIFICATE+'\n'+
that.usercertificate+'\n'+
- END_CERTIFICATE_REQUEST
+ END_CERTIFICATE
);
that.open = function() {
@@ -371,3 +388,291 @@ function certificate_request_dialog(spec) {
return that;
}
+
+function certificate_status_panel(spec) {
+ var that = $('<div/>');
+ spec = spec || {};
+
+ that.entity_type = spec.entity_type;
+ that.entity_label = spec.entity_label || that.entity_type;
+
+ that.result = spec.result;
+
+ that.get_entity_pkey = spec.get_entity_pkey;
+ that.get_entity_name = spec.get_entity_name;
+ that.get_entity_principal = spec.get_entity_principal;
+ that.get_entity_certificate = spec.get_entity_certificate;
+
+ var li1, li2, li3;
+
+ function init() {
+ var pkey = that.get_entity_pkey(that.result);
+
+ var table = $('<table/>').appendTo(that);
+
+ var tr = $('<tr/>').appendTo(table);
+
+ var td = $('<td/>').appendTo(tr);
+ li1 = $('<li/>', {
+ 'class': 'certificate-status-valid'
+ }).appendTo(td);
+
+ td = $('<td/>').appendTo(tr);
+ td.append('Valid Certificate Present:');
+
+ td = $('<td/>').appendTo(tr);
+ $('<input/>', {
+ 'id': 'get_button',
+ 'type': 'button',
+ 'value': 'Get',
+ 'click': function() {
+ ipa_cmd(that.entity_type+'_show', [pkey], {},
+ function(data, text_status, xhr) {
+ get_certificate(data.result.result);
+ }
+ );
+ }
+ }).appendTo(td);
+
+ $('<input/>', {
+ 'id': 'revoke_button',
+ 'type': 'button',
+ 'value': 'Revoke',
+ 'click': function() {
+ ipa_cmd(that.entity_type+'_show', [pkey], {},
+ function(data, text_status, xhr) {
+ revoke_certificate(data.result.result);
+ }
+ );
+ }
+ }).appendTo(td);
+
+ $('<input/>', {
+ 'id': 'view_button',
+ 'type': 'button',
+ 'value': 'View',
+ 'click': function() {
+ ipa_cmd(that.entity_type+'_show', [pkey], {},
+ function(data, text_status, xhr) {
+ view_certificate(data.result.result);
+ }
+ );
+ }
+ }).appendTo(td);
+
+ tr = $('<tr/>').appendTo(table);
+
+ td = $('<td/>').appendTo(tr);
+ li2 = $('<li/>', {
+ 'class': 'certificate-status-revoked'
+ }).appendTo(td);
+
+ td = $('<td/>').appendTo(tr);
+ td.append('Certificate Revoked:');
+
+ td = $('<td/>').appendTo(tr);
+ td.append($('<span/>', {
+ 'id': 'revocation_reason'
+ }));
+ td.append(' ');
+
+ $('<input/>', {
+ 'id': 'restore_button',
+ 'type': 'button',
+ 'value': 'Restore',
+ 'click': function() {
+ ipa_cmd(that.entity_type+'_show', [pkey], {},
+ function(data, text_status, xhr) {
+ restore_certificate(data.result.result);
+ }
+ );
+ }
+ }).appendTo(td);
+
+ tr = $('<tr/>').appendTo(table);
+
+ td = $('<td/>').appendTo(tr);
+ li3 = $('<li/>', {
+ 'class': 'certificate-status-missing'
+ }).appendTo(td);
+
+ td = $('<td/>').appendTo(tr);
+ td.append('No Valid Certificate:');
+
+ td = $('<td/>').appendTo(tr);
+ $('<input/>', {
+ 'type': 'button',
+ 'value': 'New Certificate',
+ 'click': function() {
+ request_certificate(that.result);
+ }
+ }).appendTo(td);
+
+ var entity_certificate = that.get_entity_certificate(that.result);
+ if (entity_certificate) {
+ check_status(that.result.serial_number);
+ } else {
+ set_status(CERTIFICATE_STATUS_MISSING);
+ }
+ }
+
+ function set_status(status, revocation_reason) {
+ li1.toggleClass('certificate-status-active', status == CERTIFICATE_STATUS_VALID);
+ li2.toggleClass('certificate-status-active', status == CERTIFICATE_STATUS_REVOKED);
+ li3.toggleClass('certificate-status-active', status == CERTIFICATE_STATUS_MISSING);
+
+ $('#get_button', that).css('visibility', status == CERTIFICATE_STATUS_VALID ? 'visible' : 'hidden');
+ $('#revoke_button', that).css('visibility', status == CERTIFICATE_STATUS_VALID ? 'visible' : 'hidden');
+ $('#view_button', that).css('visibility', status == CERTIFICATE_STATUS_VALID ? 'visible' : 'hidden');
+ $('#revocation_reason', that).html(revocation_reason == undefined ? '' : CRL_REASON[revocation_reason]);
+ $('#restore_button', that).css('visibility', revocation_reason == 6 ? 'visible' : 'hidden');
+ }
+
+ function check_status(serial_number) {
+ ipa_cmd(
+ 'cert_show',
+ [serial_number],
+ { },
+ function(data, text_status, xhr) {
+ var revocation_reason = data.result.result.revocation_reason;
+ if (revocation_reason == undefined) {
+ set_status(CERTIFICATE_STATUS_VALID);
+ } else {
+ set_status(CERTIFICATE_STATUS_REVOKED, revocation_reason);
+ }
+ }
+ );
+ }
+
+ function view_certificate(result) {
+
+ var entity_certificate = that.get_entity_certificate(result);
+ if (!entity_certificate) {
+ set_status(CERTIFICATE_STATUS_MISSING);
+ return;
+ }
+
+ var entity_name = that.get_entity_name(result);
+
+ var dialog = certificate_view_dialog({
+ 'title': 'Certificate for '+that.entity_label+' '+entity_name,
+ 'subject': result['subject'],
+ 'serial_number': result['serial_number'],
+ 'issuer': result['issuer'],
+ 'issued_on': result['valid_not_before'],
+ 'expires_on': result['valid_not_after'],
+ 'md5_fingerprint': result['md5_fingerprint'],
+ 'sha1_fingerprint': result['sha1_fingerprint']
+ });
+
+ dialog.open();
+ }
+
+ function get_certificate(result) {
+
+ var entity_certificate = that.get_entity_certificate(result);
+ if (!entity_certificate) {
+ set_status(CERTIFICATE_STATUS_MISSING);
+ return;
+ }
+
+ var entity_name = that.get_entity_name(result);
+
+ var dialog = certificate_get_dialog({
+ 'title': 'Certificate for '+that.entity_label+' '+entity_name,
+ 'usercertificate': entity_certificate
+ });
+
+ dialog.open();
+ }
+
+ function request_certificate(result) {
+
+ var entity_name = that.get_entity_name(result);
+ var entity_principal = that.get_entity_principal(result);
+
+ var dialog = certificate_request_dialog({
+ 'title': 'Issue New Certificate for '+that.entity_label+' '+entity_name,
+ 'request': function(values) {
+ var request = values['request'];
+
+ ipa_cmd(
+ 'cert_request',
+ [request],
+ {
+ 'principal': entity_principal
+ },
+ function(data, text_status, xhr) {
+ check_status(data.result.result.serial_number);
+ }
+ );
+ }
+ });
+
+ dialog.open();
+ }
+
+ function revoke_certificate(result) {
+
+ var entity_certificate = that.get_entity_certificate(result);
+ if (!entity_certificate) {
+ set_status(CERTIFICATE_STATUS_MISSING);
+ return;
+ }
+
+ var entity_name = that.get_entity_name(result);
+ var serial_number = result['serial_number'];
+
+ var dialog = certificate_revoke_dialog({
+ 'title': 'Revoke Certificate for '+that.entity_label+' '+entity_name,
+ 'revoke': function(values) {
+ var reason = values['reason'];
+
+ ipa_cmd(
+ 'cert_revoke',
+ [serial_number],
+ {
+ 'revocation_reason': reason
+ },
+ function(data, text_status, xhr) {
+ check_status(serial_number);
+ }
+ );
+ }
+ });
+
+ dialog.open();
+ }
+
+ function restore_certificate(result) {
+
+ var entity_certificate = that.get_entity_certificate(result);
+ if (!entity_certificate) {
+ set_status(CERTIFICATE_STATUS_MISSING);
+ return;
+ }
+
+ var entity_name = that.get_entity_name(result);
+ var serial_number = result['serial_number'];
+
+ var dialog = certificate_restore_dialog({
+ 'title': 'Restore Certificate for '+that.entity_label+' '+entity_name,
+ 'restore': function(values) {
+ ipa_cmd(
+ 'cert_remove_hold',
+ [serial_number],
+ { },
+ function(data, text_status, xhr) {
+ check_status(serial_number);
+ }
+ );
+ }
+ });
+
+ dialog.open();
+ }
+
+ init();
+
+ return that;
+}
diff --git a/install/static/host.js b/install/static/host.js
index d2cdd7d5..c4d110a8 100644
--- a/install/static/host.js
+++ b/install/static/host.js
@@ -35,13 +35,50 @@ ipa_entity_set_add_definition('host', [
]);
ipa_entity_set_details_definition('host', [
- ipa_stanza({name:'host', label:'Host Details'}).
+ ipa_stanza({name:'details', label:'Host Details'}).
input({name:'fqdn', label:'Fully Qualified Domain Name'}).
input({name:'krbprincipalname', label:'Kerberos Principal'}).
- input({name:'serverhostname', label:'Server Host Name'})
+ input({name:'serverhostname', label:'Server Host Name'}),
+ ipa_stanza({name:'enrollment', label:'Enrollment'}).
+ input({name:'enrollment_status', label:'Status',
+ load:host_enrollment_status_load}),
+ ipa_stanza({name:'certificate', label:'Host Certificate'}).
+ input({name:'certificate_status', label:'Status',
+ load:host_usercertificate_load})
]);
ipa_entity_set_association_definition('host', {
'hostgroup': { associator: SerialAssociator },
'rolegroup': { associator: SerialAssociator }
});
+
+function host_enrollment_status_load(container, dt, result) {
+ // skip enrollment_status
+}
+
+function host_usercertificate_load(container, dt, result) {
+
+ var panel = certificate_status_panel({
+ 'entity_type': 'host',
+ 'entity_label': 'Host',
+ 'result': result,
+ 'get_entity_pkey': function(result) {
+ var values = result['fqdn'];
+ return values ? values[0] : null;
+ },
+ 'get_entity_name': function(result) {
+ return this.get_entity_pkey(result);
+ },
+ 'get_entity_principal': function(result) {
+ var values = result['krbprincipalname'];
+ return values ? values[0] : null;
+ },
+ 'get_entity_certificate': function(result) {
+ var values = result['usercertificate'];
+ return values ? values[0].__base64__ : null;
+ }
+ });
+
+ var dd = ipa_create_first_dd(this.name, panel);
+ dt.after(dd);
+}
diff --git a/install/static/ipa.css b/install/static/ipa.css
index f8b74bca..908875b8 100644
--- a/install/static/ipa.css
+++ b/install/static/ipa.css
@@ -278,3 +278,22 @@ span.main-separator{
}
.strikethrough { text-decoration: line-through; }
+
+.certificate-status-valid {
+ list-style-type: circle;
+ color: #008000;
+}
+
+.certificate-status-revoked {
+ list-style-type: circle;
+ color: #ff0000;
+}
+
+.certificate-status-missing {
+ list-style-type: circle;
+ color: #daa520;
+}
+
+.certificate-status-active {
+ list-style-type: disc;
+}
diff --git a/install/static/service.js b/install/static/service.js
index 5e37f6a7..620c1bab 100644
--- a/install/static/service.js
+++ b/install/static/service.js
@@ -20,10 +20,6 @@
/* REQUIRES: ipa.js, details.js, search.js, add.js, entity.js */
-var SERVICE_CERTIFICATE_VALID = 1;
-var SERVICE_CERTIFICATE_REVOKED = 2;
-var SERVICE_CERTIFICATE_MISSING = 3;
-
ipa_entity_set_search_definition('service', [
['krbprincipalname', 'Principal', null],
['quick_links', 'Quick Links', ipa_entity_quick_links]
@@ -94,273 +90,27 @@ function service_provisioning_status_load(container, dt, result) {
function service_usercertificate_load(container, dt, result) {
- var li1, li2, li3;
-
- function set_status(status, revocation_reason) {
- li1.css('list-style-type', status == SERVICE_CERTIFICATE_VALID ? 'disc' : 'circle');
- li2.css('list-style-type', status == SERVICE_CERTIFICATE_REVOKED ? 'disc' : 'circle');
- li3.css('list-style-type', status == SERVICE_CERTIFICATE_MISSING ? 'disc' : 'circle');
-
- $('#revocation_reason').html(revocation_reason ? CRL_REASON[revocation_reason] : '');
- $('#restore_button').css('visibility', revocation_reason == 6 ? 'visible' : 'hidden')
- }
-
- function check_status(serial_number) {
- ipa_cmd(
- 'cert_show',
- [serial_number],
- { },
- function(data, text_status, xhr) {
- var revocation_reason = data.result.result.revocation_reason;
- if (revocation_reason) {
- set_status(SERVICE_CERTIFICATE_REVOKED, revocation_reason);
- } else {
- set_status(SERVICE_CERTIFICATE_VALID);
- }
- }
- );
- }
-
- function get_certificate(result) {
-
- var usercertificate = result['usercertificate'];
- if (!usercertificate) {
- set_status(SERVICE_CERTIFICATE_MISSING);
- return;
- }
-
- var krbprincipalname = result['krbprincipalname'][0];
- var service_name = krbprincipalname.replace(/@.*$/, '');
-
- var dialog = certificate_get_dialog({
- 'title': 'Certificate for Service '+service_name,
- 'usercertificate': usercertificate[0].__base64__
- });
-
- dialog.open();
- }
-
- function view_certificate(result) {
-
- var usercertificate = result['usercertificate'];
- if (!usercertificate) {
- set_status(SERVICE_CERTIFICATE_MISSING);
- return;
- }
-
- var krbprincipalname = result['krbprincipalname'][0];
- var service_name = krbprincipalname.replace(/@.*$/, '');
-
- var dialog = certificate_view_dialog({
- 'title': 'Certificate for Service '+service_name,
- 'subject': result['subject'],
- 'serial_number': result['serial_number'],
- 'issuer': result['issuer'],
- 'issued_on': result['valid_not_before'],
- 'expires_on': result['valid_not_after'],
- 'md5_fingerprint': result['md5_fingerprint'],
- 'sha1_fingerprint': result['sha1_fingerprint']
- });
-
- dialog.open();
- }
-
- function revoke_certificate(result) {
-
- var usercertificate = result['usercertificate'];
- if (!usercertificate) {
- set_status(SERVICE_CERTIFICATE_MISSING);
- return;
+ var panel = certificate_status_panel({
+ 'entity_type': 'service',
+ 'entity_label': 'Service',
+ 'result': result,
+ 'get_entity_pkey': function(result) {
+ var values = result['krbprincipalname'];
+ return values ? values[0] : null;
+ },
+ 'get_entity_name': function(result) {
+ var value = this.get_entity_pkey(result);
+ return value ? value.replace(/@.*$/, '') : null;
+ },
+ 'get_entity_principal': function(result) {
+ return this.get_entity_pkey(result);
+ },
+ 'get_entity_certificate': function(result) {
+ var values = result['usercertificate'];
+ return values ? values[0].__base64__ : null;
}
+ });
- var krbprincipalname = result['krbprincipalname'][0];
- var service_name = krbprincipalname.replace(/@.*$/, '');
-
- var serial_number = result['serial_number'];
-
- var dialog = certificate_revoke_dialog({
- 'title': 'Revoke Certificate for Service '+service_name,
- 'revoke': function(values) {
- var reason = values['reason'];
-
- ipa_cmd(
- 'cert_revoke',
- [serial_number],
- {
- 'revocation_reason': reason
- },
- function(data, text_status, xhr) {
- check_status(serial_number);
- }
- );
- }
- });
-
- dialog.open();
- }
-
- function restore_certificate(result) {
-
- var usercertificate = result['usercertificate'];
- if (!usercertificate) {
- set_status(SERVICE_CERTIFICATE_MISSING);
- return;
- }
-
- var krbprincipalname = result['krbprincipalname'][0];
- var service_name = krbprincipalname.replace(/@.*$/, '');
-
- var serial_number = result['serial_number'];
-
- var dialog = certificate_restore_dialog({
- 'title': 'Restore Certificate for Service '+service_name,
- 'restore': function(values) {
- ipa_cmd(
- 'cert_remove_hold',
- [serial_number],
- { },
- function(data, text_status, xhr) {
- check_status(serial_number);
- }
- );
- }
- });
-
- dialog.open();
- }
-
- function request_certificate(result) {
-
- var krbprincipalname = result['krbprincipalname'][0];
- var service_name = krbprincipalname.replace(/@.*$/, '');
-
- var dialog = certificate_request_dialog({
- 'title': 'Issue New Certificate for Service '+service_name,
- 'request': function(values) {
- var request = values['request'];
-
- ipa_cmd(
- 'cert_request',
- [request],
- {
- 'principal': krbprincipalname
- },
- function(data, text_status, xhr) {
- check_status(data.result.result.serial_number);
- }
- );
- }
- });
-
- dialog.open();
- }
-
- var krbprincipalname = result['krbprincipalname'][0];
-
- var table = $('<table/>');
-
- var tr = $('<tr/>').appendTo(table);
-
- var td = $('<td/>').appendTo(tr);
- li1 = $('<li/>', {
- style: 'color: green;'
- }).appendTo(td);
-
- td = $('<td/>').appendTo(tr);
- td.append('Valid Certificate Present:');
-
- td = $('<td/>').appendTo(tr);
- $('<input/>', {
- 'type': 'button',
- 'value': 'Get',
- 'click': function() {
- ipa_cmd('service_show', [krbprincipalname], {},
- function(data, text_status, xhr) {
- get_certificate(data.result.result);
- }
- );
- }
- }).appendTo(td);
-
- $('<input/>', {
- 'type': 'button',
- 'value': 'Revoke',
- 'click': function() {
- ipa_cmd('service_show', [krbprincipalname], {},
- function(data, text_status, xhr) {
- revoke_certificate(data.result.result);
- }
- );
- }
- }).appendTo(td);
-
- $('<input/>', {
- 'type': 'button',
- 'value': 'View',
- 'click': function() {
- ipa_cmd('service_show', [krbprincipalname], {},
- function(data, text_status, xhr) {
- view_certificate(data.result.result);
- }
- );
- }
- }).appendTo(td);
-
- tr = $('<tr/>').appendTo(table);
-
- td = $('<td/>').appendTo(tr);
- li2 = $('<li/>', {
- 'style': 'color: red;'
- }).appendTo(td);
-
- td = $('<td/>').appendTo(tr);
- td.append('Certificate Revoked:');
-
- td = $('<td/>').appendTo(tr);
- td.append($('<span/>', {
- 'id': 'revocation_reason'
- }));
- td.append(' ');
-
- $('<input/>', {
- 'id': 'restore_button',
- 'type': 'button',
- 'value': 'Restore',
- 'click': function() {
- ipa_cmd('service_show', [krbprincipalname], {},
- function(data, text_status, xhr) {
- restore_certificate(data.result.result);
- }
- );
- }
- }).appendTo(td);
-
- tr = $('<tr/>').appendTo(table);
-
- td = $('<td/>').appendTo(tr);
- li3 = $('<li/>', {
- 'style': 'color: goldenrod;'
- }).appendTo(td);
-
- td = $('<td/>').appendTo(tr);
- td.append('No Valid Certificate:');
-
- td = $('<td/>').appendTo(tr);
- $('<input/>', {
- 'type': 'button',
- 'value': 'New Certificate',
- 'click': function() {
- request_certificate(result);
- }
- }).appendTo(td);
-
- var dd = ipa_create_first_dd(this.name, table);
+ var dd = ipa_create_first_dd(this.name, panel);
dt.after(dd);
-
- var usercertificate = result['usercertificate'];
- if (usercertificate) {
- check_status(result.serial_number);
- } else {
- set_status(SERVICE_CERTIFICATE_MISSING);
- }
}
diff --git a/install/static/test/all_tests.html b/install/static/test/all_tests.html
index aede08e7..50c5155d 100644
--- a/install/static/test/all_tests.html
+++ b/install/static/test/all_tests.html
@@ -14,11 +14,13 @@
<script type="text/javascript" src="../entity.js"></script>
<script type="text/javascript" src="../associate.js"></script>
<script type="text/javascript" src="../navigation.js"></script>
+ <script type="text/javascript" src="../certificate.js"></script>
<script type="text/javascript" src="ipa_tests.js"></script>
<script type="text/javascript" src="details_tests.js"></script>
<script type="text/javascript" src="entity_tests.js"></script>
<script type="text/javascript" src="association_tests.js"></script>
<script type="text/javascript" src="navigation_tests.js"></script>
+ <script type="text/javascript" src="certificate_tests.js"></script>
</head>
<body>
<h1 id="qunit-header">Complete Test Suite</h1>
@@ -26,6 +28,6 @@
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
- <div id="qunit-fixture">test markup</div>
+ <div id="qunit-fixture"></div>
</body>
</html>
diff --git a/install/static/test/association_tests.html b/install/static/test/association_tests.html
index 5b5fb717..40b3c208 100644
--- a/install/static/test/association_tests.html
+++ b/install/static/test/association_tests.html
@@ -18,6 +18,6 @@
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
- <div id="qunit-fixture">test markup</div>
+ <div id="qunit-fixture"></div>
</body>
</html>
diff --git a/install/static/test/certificate_tests.html b/install/static/test/certificate_tests.html
new file mode 100755
index 00000000..90f09b21
--- /dev/null
+++ b/install/static/test/certificate_tests.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Certificate Test Suite</title>
+ <link rel="stylesheet" href="qunit.css" type="text/css" media="screen">
+ <script type="text/javascript" src="qunit.js"></script>
+ <script type="text/javascript" src="../jquery.js"></script>
+ <script type="text/javascript" src="../ipa.js"></script>
+ <script type="text/javascript" src="../details.js"></script>
+ <script type="text/javascript" src="../search.js"></script>
+ <script type="text/javascript" src="../add.js"></script>
+ <script type="text/javascript" src="../navigation.js"></script>
+ <script type="text/javascript" src="../certificate.js"></script>
+ <script type="text/javascript" src="certificate_tests.js"></script>
+</head>
+<body>
+ <h1 id="qunit-header">Certificate Test Suite</h1>
+ <h2 id="qunit-banner"></h2>
+ <div id="qunit-testrunner-toolbar"></div>
+ <h2 id="qunit-userAgent"></h2>
+ <ol id="qunit-tests"></ol>
+ <div id="qunit-fixture"></div>
+</body>
+</html>
diff --git a/install/static/test/certificate_tests.js b/install/static/test/certificate_tests.js
new file mode 100755
index 00000000..6ada6e40
--- /dev/null
+++ b/install/static/test/certificate_tests.js
@@ -0,0 +1,79 @@
+/* Authors:
+ * Endi Sukma Dewata <edewata@redhat.com>
+ *
+ * Copyright (C) 2010 Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 only
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+test("Testing certificate_parse_dn().", function() {
+
+ same(
+ certificate_parse_dn(), {},
+ "Checking certificate_parse_dn()"
+ );
+
+ same(
+ certificate_parse_dn(''), {},
+ "Checking certificate_parse_dn('')"
+ );
+
+ same(
+ certificate_parse_dn('c=US'), {'c': 'US'},
+ "Checking certificate_parse_dn('c=US')"
+ );
+
+ same(
+ certificate_parse_dn('st=TX,c=US'), {'st': 'TX','c': 'US'},
+ "Checking certificate_parse_dn('st=TX,c=US')"
+ );
+
+ same(
+ certificate_parse_dn('c=US,st=TX'), {'st': 'TX','c': 'US'},
+ "Checking certificate_parse_dn('c=US,st=TX')"
+ );
+
+ same(
+ certificate_parse_dn(' st = New Mexico , c = US '), {'st': 'New Mexico','c': 'US'},
+ "Checking certificate_parse_dn(' st = New Mexico , c = US ')"
+ );
+
+ same(
+ certificate_parse_dn('ST=TX,C=US'), {'st': 'TX','c': 'US'},
+ "Checking certificate_parse_dn('ST=TX,C=US')"
+ );
+
+ same(
+ certificate_parse_dn('cn=dev.example.com,ou=Engineering,o=Example,l=Austin,ST=TX,C=US'),
+ { 'cn': 'dev.example.com',
+ 'ou': 'Engineering',
+ 'o': 'Example',
+ 'l': 'Austin',
+ 'st': 'TX',
+ 'c': 'US'
+ },
+ "Checking certificate_parse_dn('cn=dev.example.com,ou=Engineering,o=Example,l=Austin,ST=TX,C=US')"
+ );
+
+ same(
+ certificate_parse_dn('cn=John Smith,ou=Developers,ou=Users,dc=example,dc=com'),
+ {
+ 'cn': 'John Smith',
+ 'ou': ['Developers','Users'],
+ 'dc': ['example', 'com']
+ },
+ "Checking certificate_parse_dn('cn=John Smith,ou=Developers,ou=Users,dc=example,dc=com')"
+ );
+});
diff --git a/install/static/test/data/cert_show.json b/install/static/test/data/cert_show.json
index f8996715..71d895f0 100644
--- a/install/static/test/data/cert_show.json
+++ b/install/static/test/data/cert_show.json
@@ -6,7 +6,6 @@
"certificate": "MIICAjCCAWugAwIBAgICBAswDQYJKoZIhvcNAQEFBQAwKTEnMCUGA1UEAxMeSVBBIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMTAwNzIzMzk0NFoXDTE1MTAwNzIzMzk0NFowKDEMMAoGA1UECgwDSVBBMRgwFgYDVQQDDA9kZXYuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOTXyj8grVB7Rj95RFawgdwn9OYZ03LWHZ+HMYggu2/xCCrUrdThP14YBlVqZumjVJSclj6T4ACjjdPJq9JTTmx7gMizDTReus7IPlS6fCxb5v5whQJZsEksXL04OxUMl25euPRFkYcTK1rdW47+AkG10j1qeNW+B6CpdQGR6eM/AgMBAAGjOjA4MBEGCWCGSAGG+EIBAQQEAwIGQDATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADgYEASIhq723VL5xP0q51MYXFlGU1boD7pPD1pIQspD/MjCIEupcbH2kAo4wf+EiKsXR0rs+WZkaSgvFqaM4OQ2kWSFTiqmFXFDBEi6EFr68yLg7IpQpNTzVBXERd8B4GwNL9wrRw60jPXlUK29DPBsdGq8fDgX18l39wKkWXv7p1to4=",
"issuer": "CN=Certificate Authority,O=IPA",
"md5_fingerprint": "08:86:a9:f9:87:af:0d:d7:42:01:e0:5f:12:9b:32:7f",
- "revocation_reason": 6,
"serial_number": "1",
"sha1_fingerprint": "b8:4c:4b:79:4f:13:03:79:47:08:fa:6b:52:63:3d:f9:15:8e:7e:dc",
"subject": "CN=dev.example.com,O=IPA",
diff --git a/install/static/test/data/host_show.json b/install/static/test/data/host_show.json
index 64a7fb31..b0916215 100644
--- a/install/static/test/data/host_show.json
+++ b/install/static/test/data/host_show.json
@@ -14,6 +14,7 @@
"ipauniqueid": [
"b54b73a8-8ba8-11df-80bc-00163e26b89e"
],
+ "issuer": "CN=IPA Test Certificate Authority",
"krbextradata": [
{
"__base64__": "AAKOoTdMYWRtaW4vYWRtaW5ASURNLkxBQi5CT1MuUkVESEFULkNPTQA="
@@ -34,6 +35,7 @@
"managedby": [
"fqdn=vm-121.idm.lab.bos.redhat.com,cn=computers,cn=accounts,dc=idm,dc=lab,dc=bos,dc=redhat,dc=com"
],
+ "md5_fingerprint": "08:86:a9:f9:87:af:0d:d7:42:01:e0:5f:12:9b:32:7f",
"memberof": [],
"objectclass": [
"top",
@@ -46,9 +48,19 @@
"krbprincipal",
"krbticketpolicyaux"
],
+ "serial_number": "1",
"serverhostname": [
"vm-121"
- ]
+ ],
+ "sha1_fingerprint": "b8:4c:4b:79:4f:13:03:79:47:08:fa:6b:52:63:3d:f9:15:8e:7e:dc",
+ "subject": "CN=dev.example.com,O=IPA",
+ "usercertificate": [
+ {
+ "__base64__": "MIICAjCCAWugAwIBAgICBAswDQYJKoZIhvcNAQEFBQAwKTEnMCUGA1UEAxMeSVBBIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMTAwNzIzMzk0NFoXDTE1MTAwNzIzMzk0NFowKDEMMAoGA1UECgwDSVBBMRgwFgYDVQQDDA9kZXYuZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOTXyj8grVB7Rj95RFawgdwn9OYZ03LWHZ+HMYggu2/xCCrUrdThP14YBlVqZumjVJSclj6T4ACjjdPJq9JTTmx7gMizDTReus7IPlS6fCxb5v5whQJZsEksXL04OxUMl25euPRFkYcTK1rdW47+AkG10j1qeNW+B6CpdQGR6eM/AgMBAAGjOjA4MBEGCWCGSAGG+EIBAQQEAwIGQDATBgNVHSUEDDAKBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMCBPAwDQYJKoZIhvcNAQEFBQADgYEASIhq723VL5xP0q51MYXFlGU1boD7pPD1pIQspD/MjCIEupcbH2kAo4wf+EiKsXR0rs+WZkaSgvFqaM4OQ2kWSFTiqmFXFDBEi6EFr68yLg7IpQpNTzVBXERd8B4GwNL9wrRw60jPXlUK29DPBsdGq8fDgX18l39wKkWXv7p1to4="
+ }
+ ],
+ "valid_not_after": "Tue Oct 13 01:59:32 2015 UTC",
+ "valid_not_before": "Wed Oct 13 01:59:32 2010 UTC"
},
"summary": null,
"value": "vm-121.idm.lab.bos.redhat.com"
diff --git a/install/static/test/details_tests.html b/install/static/test/details_tests.html
index 7c323610..e96fa4b7 100644
--- a/install/static/test/details_tests.html
+++ b/install/static/test/details_tests.html
@@ -19,6 +19,6 @@
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
- <div id="qunit-fixture">test markup</div>
+ <div id="qunit-fixture"></div>
</body>
</html>
diff --git a/install/static/test/entity_tests.html b/install/static/test/entity_tests.html
index a6d3f72f..b8da0f44 100644
--- a/install/static/test/entity_tests.html
+++ b/install/static/test/entity_tests.html
@@ -19,6 +19,6 @@
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
- <div id="qunit-fixture">test markup</div>
+ <div id="qunit-fixture"></div>
</body>
</html>
diff --git a/install/static/test/index.html b/install/static/test/index.html
index a71ee60f..5467a683 100644
--- a/install/static/test/index.html
+++ b/install/static/test/index.html
@@ -29,6 +29,7 @@
<li><a href="details_tests.html">Details Test Suite</a>
<li><a href="association_tests.html">Association Test Suite</a>
<li><a href="navigation_tests.html">Navigation Test Suite</a>
+ <li><a href="certificate_tests.html">Certificate Test Suite</a>
</ul>
</div>
diff --git a/install/static/test/ipa_tests.html b/install/static/test/ipa_tests.html
index dfe2720a..3f3c1686 100644
--- a/install/static/test/ipa_tests.html
+++ b/install/static/test/ipa_tests.html
@@ -17,6 +17,6 @@
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
- <div id="qunit-fixture">test markup</div>
+ <div id="qunit-fixture"></div>
</body>
</html>
diff --git a/install/static/test/navigation_tests.html b/install/static/test/navigation_tests.html
index dbb562f1..fa911d6e 100644
--- a/install/static/test/navigation_tests.html
+++ b/install/static/test/navigation_tests.html
@@ -16,6 +16,6 @@
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
- <div id="qunit-fixture">test markup</div>
+ <div id="qunit-fixture"></div>
</body>
</html>
diff --git a/ipalib/plugins/host.py b/ipalib/plugins/host.py
index d207f526..3a63d212 100644
--- a/ipalib/plugins/host.py
+++ b/ipalib/plugins/host.py
@@ -76,6 +76,7 @@ from ipalib.plugins.service import validate_certificate
from ipalib import _, ngettext
from ipalib import x509
import base64
+import nss.nss as nss
def validate_host(ugettext, fqdn):
@@ -335,6 +336,30 @@ class host_show(LDAPRetrieve):
has_output_params = (
Flag('has_keytab',
label=_('Keytab'),
+ ),
+ Str('subject',
+ label=_('Subject'),
+ ),
+ Str('serial_number',
+ label=_('Serial Number'),
+ ),
+ Str('issuer',
+ label=_('Issuer'),
+ ),
+ Str('valid_not_before',
+ label=_('Not Before'),
+ ),
+ Str('valid_not_after',
+ label=_('Not After'),
+ ),
+ Str('md5_fingerprint',
+ label=_('Fingerprint (MD5)'),
+ ),
+ Str('sha1_fingerprint',
+ label=_('Fingerprint (SHA1)'),
+ ),
+ Str('revocation_reason?',
+ label=_('Revocation reason'),
)
)
@@ -346,6 +371,16 @@ class host_show(LDAPRetrieve):
else:
entry_attrs['has_keytab'] = False
+ if 'usercertificate' in entry_attrs:
+ cert = x509.load_certificate(entry_attrs['usercertificate'][0], datatype=x509.DER)
+ entry_attrs['subject'] = unicode(cert.subject)
+ entry_attrs['serial_number'] = unicode(cert.serial_number)
+ entry_attrs['issuer'] = unicode(cert.issuer)
+ entry_attrs['valid_not_before'] = unicode(cert.valid_not_before_str)
+ entry_attrs['valid_not_after'] = unicode(cert.valid_not_after_str)
+ entry_attrs['md5_fingerprint'] = unicode(nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
+ entry_attrs['sha1_fingerprint'] = unicode(nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])
+
return dn
api.register(host_show)