diff options
-rwxr-xr-x | install/static/certificate.js | 317 | ||||
-rw-r--r-- | install/static/host.js | 41 | ||||
-rw-r--r-- | install/static/ipa.css | 19 | ||||
-rw-r--r-- | install/static/service.js | 290 | ||||
-rw-r--r-- | install/static/test/all_tests.html | 4 | ||||
-rw-r--r-- | install/static/test/association_tests.html | 2 | ||||
-rwxr-xr-x | install/static/test/certificate_tests.html | 24 | ||||
-rwxr-xr-x | install/static/test/certificate_tests.js | 79 | ||||
-rw-r--r-- | install/static/test/data/cert_show.json | 1 | ||||
-rw-r--r-- | install/static/test/data/host_show.json | 14 | ||||
-rw-r--r-- | install/static/test/details_tests.html | 2 | ||||
-rw-r--r-- | install/static/test/entity_tests.html | 2 | ||||
-rw-r--r-- | install/static/test/index.html | 1 | ||||
-rw-r--r-- | install/static/test/ipa_tests.html | 2 | ||||
-rw-r--r-- | install/static/test/navigation_tests.html | 2 | ||||
-rw-r--r-- | ipalib/plugins/host.py | 35 |
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) |