mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2026-09-03 20:52:56 -05:00
Service certificate UI.
The service.py has been modified to include certificate info in the service-show result if the service contains usercertificate. A new file certificate.js has been added to store codes related to certificates (e.g. revocation reasons, dialog boxes). The service.js has been modified to provide the UI for certificate management. The certificate.js can also be used for host certificate management. The Makefile.am and index.xhtml has been modified to include certificate.js. New test data files have been added for certificate operations. To test revoke and restore operations the server needs to be installed with dogtag CA instead of self-signed CA. The certificate status and revocation reason in the details page will be implemented in subsequent patches. Unit tests will also be added in subsequent patches.
This commit is contained in:
committed by
Adam Young
parent
acf5f9cad7
commit
4c24581b5c
@@ -20,6 +20,7 @@ app_DATA = \
|
||||
jquery-ui.js \
|
||||
jquery.ba-bbq.js \
|
||||
jquery-ui.css \
|
||||
certificate.js \
|
||||
group.js \
|
||||
host.js \
|
||||
hostgroup.js \
|
||||
|
||||
Executable
+381
@@ -0,0 +1,381 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
var BEGIN_CERTIFICATE_REQUEST = '-----BEGIN CERTIFICATE REQUEST-----';
|
||||
var END_CERTIFICATE_REQUEST = '-----END CERTIFICATE REQUEST-----';
|
||||
|
||||
var CRL_REASON = [
|
||||
'Unspecified',
|
||||
'Key Compromise',
|
||||
'CA Compromise',
|
||||
'Affiliation Changed',
|
||||
'Superseded',
|
||||
'Cessation of Operation',
|
||||
'Certificate Hold',
|
||||
null,
|
||||
'Remove from CRL',
|
||||
'Privilege Withdrawn',
|
||||
'AA Compromise'
|
||||
];
|
||||
|
||||
function certificate_parse_dn(dn) {
|
||||
|
||||
var 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];
|
||||
|
||||
result[name] = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function certificate_confirmation_dialog(spec) {
|
||||
var that = {};
|
||||
spec = spec || {};
|
||||
|
||||
var dialog = $('<div/>', {
|
||||
'title': spec.title
|
||||
});
|
||||
|
||||
dialog.append(spec.message);
|
||||
|
||||
that.open = function() {
|
||||
dialog.dialog({
|
||||
modal: true,
|
||||
width: 300,
|
||||
height: 150,
|
||||
buttons: {
|
||||
'Close': function() {
|
||||
dialog.dialog('destroy');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return that;
|
||||
}
|
||||
|
||||
function certificate_get_dialog(spec) {
|
||||
var that = {};
|
||||
spec = spec || {};
|
||||
|
||||
var dialog = $('<div/>', {
|
||||
'title': spec.title
|
||||
});
|
||||
|
||||
var textarea = $('<textarea/>', {
|
||||
readonly: 'yes',
|
||||
style: 'width: 100%; height: 275px;'
|
||||
}).appendTo(dialog);
|
||||
|
||||
textarea.val(
|
||||
BEGIN_CERTIFICATE_REQUEST+'\n'+
|
||||
spec.usercertificate+'\n'+
|
||||
END_CERTIFICATE_REQUEST
|
||||
);
|
||||
|
||||
that.open = function() {
|
||||
dialog.dialog({
|
||||
modal: true,
|
||||
width: 500,
|
||||
height: 400,
|
||||
buttons: {
|
||||
'Close': function() {
|
||||
dialog.dialog('destroy');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return that;
|
||||
}
|
||||
|
||||
function certificate_revoke_dialog(spec) {
|
||||
var that = {};
|
||||
spec = spec || {};
|
||||
|
||||
var dialog = $('<div/>', {
|
||||
'title': spec.title
|
||||
});
|
||||
|
||||
var table = $('<table/>').appendTo(dialog);
|
||||
|
||||
var tr = $('<tr/>').appendTo(table);
|
||||
|
||||
var td = $('<td/>').appendTo(tr);
|
||||
td.append('Note:');
|
||||
|
||||
td = $('<td/>').appendTo(tr);
|
||||
td.append(
|
||||
'To confirm your intention to revoke this certificate, '+
|
||||
'select a reason from the pull-down list, and click '+
|
||||
'the "Revoke" button.');
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
|
||||
td = $('<td/>').appendTo(tr);
|
||||
td.append('Reason for Revocation:');
|
||||
|
||||
td = $('<td/>').appendTo(tr);
|
||||
|
||||
var select = $('<select/>').appendTo(td);
|
||||
for (var i=0; i<CRL_REASON.length; i++) {
|
||||
if (!CRL_REASON[i]) continue;
|
||||
$('<option/>', {
|
||||
'value': i,
|
||||
'html': CRL_REASON[i]
|
||||
}).appendTo(select);
|
||||
}
|
||||
|
||||
that.open = function() {
|
||||
dialog.dialog({
|
||||
modal: true,
|
||||
width: 500,
|
||||
height: 300,
|
||||
buttons: {
|
||||
'Revoke': function() {
|
||||
var values = {};
|
||||
values['reason'] = select.val();
|
||||
if (spec.revoke) {
|
||||
spec.revoke(values);
|
||||
}
|
||||
dialog.dialog('destroy');
|
||||
},
|
||||
'Cancel': function() {
|
||||
dialog.dialog('destroy');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return that;
|
||||
}
|
||||
|
||||
function certificate_restore_dialog(spec) {
|
||||
var that = {};
|
||||
spec = spec || {};
|
||||
|
||||
var dialog = $('<div/>', {
|
||||
'title': spec.title
|
||||
});
|
||||
|
||||
dialog.append(
|
||||
'To confirm your intention to restore this certificate, '+
|
||||
'click the "Restore" button.');
|
||||
|
||||
that.open = function() {
|
||||
dialog.dialog({
|
||||
modal: true,
|
||||
width: 400,
|
||||
height: 200,
|
||||
buttons: {
|
||||
'Restore': function() {
|
||||
var values = {};
|
||||
if (spec.restore) {
|
||||
spec.restore(values);
|
||||
}
|
||||
dialog.dialog('destroy');
|
||||
},
|
||||
'Cancel': function() {
|
||||
dialog.dialog('destroy');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return that;
|
||||
}
|
||||
|
||||
function certificate_view_dialog(spec) {
|
||||
var that = {};
|
||||
spec = spec || {};
|
||||
|
||||
that.subject = certificate_parse_dn(spec.subject);
|
||||
that.issuer = certificate_parse_dn(spec.issuer);
|
||||
|
||||
var dialog = $('<div/>', {
|
||||
'title': spec.title
|
||||
});
|
||||
|
||||
var table = $('<table/>').appendTo(dialog);
|
||||
|
||||
var tr = $('<tr/>').appendTo(table);
|
||||
$('<td/>', {
|
||||
'colspan': 2,
|
||||
'html': '<h3>Issued To</h3>'
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>Common Name:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': that.subject.cn
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>Organization:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': that.subject.o
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>Organizational Unit:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': that.subject.ou
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>Serial Number:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': spec.serial_number
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td/>', {
|
||||
'colspan': 2,
|
||||
'html': '<h3>Issued By</h3>'
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>Common Name:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': that.issuer.cn
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>Organization:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': that.issuer.o
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>Organizational Unit:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': that.issuer.ou
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td/>', {
|
||||
'colspan': 2,
|
||||
'html': '<h3>Validity</h3>'
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>Issued On:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': spec.issued_on
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>Expires On:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': spec.expires_on
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td/>', {
|
||||
'colspan': 2,
|
||||
'html': '<h3>Fingerprints</h3>'
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>SHA1 Fingerprint:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': spec.sha1_fingerprint
|
||||
}).appendTo(tr);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
$('<td>MD5 Fingerprint:</td>').appendTo(tr);
|
||||
$('<td/>', {
|
||||
'html': spec.md5_fingerprint
|
||||
}).appendTo(tr);
|
||||
|
||||
that.open = function() {
|
||||
dialog.dialog({
|
||||
modal: true,
|
||||
width: 600,
|
||||
height: 500,
|
||||
buttons: {
|
||||
'Close': function() {
|
||||
dialog.dialog('destroy');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return that;
|
||||
}
|
||||
|
||||
function certificate_request_dialog(spec) {
|
||||
var that = {};
|
||||
spec = spec || {};
|
||||
|
||||
var dialog = $('<div/>', {
|
||||
'title': spec.title
|
||||
});
|
||||
|
||||
dialog.append('Copy and paste the Base64-encoded CSR below:');
|
||||
dialog.append('<br/>');
|
||||
dialog.append('<br/>');
|
||||
|
||||
dialog.append(BEGIN_CERTIFICATE_REQUEST);
|
||||
dialog.append('<br/>');
|
||||
|
||||
var textarea = $('<textarea/>', {
|
||||
style: 'width: 100%; height: 225px;'
|
||||
}).appendTo(dialog);
|
||||
|
||||
dialog.append('<br/>');
|
||||
dialog.append(END_CERTIFICATE_REQUEST);
|
||||
|
||||
that.open = function() {
|
||||
dialog.dialog({
|
||||
modal: true,
|
||||
width: 500,
|
||||
height: 400,
|
||||
buttons: {
|
||||
'Issue': function() {
|
||||
var values = {};
|
||||
var request = textarea.val();
|
||||
request =
|
||||
BEGIN_CERTIFICATE_REQUEST+'\n'+
|
||||
$.trim(request)+'\n'+
|
||||
END_CERTIFICATE_REQUEST+'\n';
|
||||
values['request'] = request;
|
||||
if (spec.request) {
|
||||
spec.request(values);
|
||||
}
|
||||
dialog.dialog('destroy');
|
||||
},
|
||||
'Cancel': function() {
|
||||
dialog.dialog('destroy');
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return that;
|
||||
}
|
||||
@@ -19,6 +19,7 @@
|
||||
<script type="text/javascript" src="entity.js"></script>
|
||||
<script type="text/javascript" src="navigation.js"></script>
|
||||
|
||||
<script type="text/javascript" src="certificate.js"></script>
|
||||
<script type="text/javascript" src="user.js"></script>
|
||||
<script type="text/javascript" src="group.js"></script>
|
||||
<script type="text/javascript" src="host.js"></script>
|
||||
|
||||
+227
-35
@@ -34,16 +34,19 @@ ipa_entity_set_add_definition('service', [
|
||||
]);
|
||||
|
||||
ipa_entity_set_details_definition('service', [
|
||||
ipa_stanza({name:'identity', label:'Service Details'}).
|
||||
ipa_stanza({name:'details', label:'Service Details'}).
|
||||
input({name:'krbprincipalname',
|
||||
label:'Principal',
|
||||
setup:service_krbprincipalname_setup,
|
||||
load:service_krbprincipalname_load}).
|
||||
input({name:'service', label:'Service', load:service_service_load}).
|
||||
input({name:'host', label:'Host Name', load:service_host_load}).
|
||||
input({name:'usercertificate', label:'Certificate',
|
||||
load:service_usercertificate_load,
|
||||
save:service_usercertificate_save})
|
||||
input({name:'host', label:'Host Name', load:service_host_load}),
|
||||
ipa_stanza({name:'provisioning', label:'Provisioning'}).
|
||||
input({name:'provisioning_status', label:'Status',
|
||||
load:service_provisioning_status_load}),
|
||||
ipa_stanza({name:'certificate', label:'Service Certificate'}).
|
||||
input({name:'certificate_status', label:'Status',
|
||||
load:service_usercertificate_load})
|
||||
]);
|
||||
|
||||
function service_add_krbprincipalname(add_dialog, mode) {
|
||||
@@ -76,45 +79,234 @@ function service_service_load(container, dt, result) {
|
||||
|
||||
function service_host_load(container, dt, result) {
|
||||
var krbprincipalname = result['krbprincipalname'][0];
|
||||
var host = krbprincipalname.replace(/^.*\//, '');
|
||||
var host = krbprincipalname.replace(/^.*\//, '').replace(/@.*$/, '');
|
||||
var dd = ipa_create_first_dd(this.name, host);
|
||||
dt.after(dd);
|
||||
}
|
||||
|
||||
function service_usercertificate_load(container, dt, result) {
|
||||
var textarea = $("<textarea/>", {
|
||||
title: 'usercertificate',
|
||||
style: 'width: 300px; height: 200px;'
|
||||
});
|
||||
function service_provisioning_status_load(container, dt, result) {
|
||||
// skip provisioning_status
|
||||
}
|
||||
|
||||
var dd = ipa_create_first_dd(this.name, textarea);
|
||||
dt.after(dd);
|
||||
function service_usercertificate_get(result) {
|
||||
|
||||
var usercertificate = result['usercertificate'];
|
||||
if (!usercertificate) return;
|
||||
if (!usercertificate) {
|
||||
alert('Service has no usercertificate.');
|
||||
return;
|
||||
}
|
||||
|
||||
var value = usercertificate[0].__base64__;
|
||||
textarea.val(value);
|
||||
}
|
||||
var krbprincipalname = result['krbprincipalname'][0];
|
||||
var service_name = krbprincipalname.replace(/@.*$/, '');
|
||||
|
||||
function service_usercertificate_save(container) {
|
||||
var field = this;
|
||||
var values = [];
|
||||
|
||||
var dd = $('dd[title='+field.name+']', container);
|
||||
dd.each(function () {
|
||||
var textarea = $('textarea', dd);
|
||||
if (!textarea.length) return;
|
||||
|
||||
var value = $.trim(textarea.val());
|
||||
if (value) {
|
||||
value = {'__base64__': value};
|
||||
} else {
|
||||
value = '';
|
||||
}
|
||||
|
||||
values.push(value);
|
||||
var dialog = certificate_get_dialog({
|
||||
'title': 'Certificate for Service '+service_name,
|
||||
'usercertificate': usercertificate[0].__base64__
|
||||
});
|
||||
|
||||
return values;
|
||||
dialog.open();
|
||||
}
|
||||
|
||||
function service_usercertificate_view(result) {
|
||||
|
||||
var usercertificate = result['usercertificate'];
|
||||
if (!usercertificate) {
|
||||
alert('Service has no usercertificate.');
|
||||
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 service_usercertificate_revoke(result) {
|
||||
|
||||
var usercertificate = result['usercertificate'];
|
||||
if (!usercertificate) {
|
||||
alert('Service has no usercertificate.');
|
||||
return;
|
||||
}
|
||||
|
||||
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) {
|
||||
var dialog = certificate_confirmation_dialog({
|
||||
title: 'Success',
|
||||
message: 'Certificate has been revoked successfully.'
|
||||
});
|
||||
dialog.open();
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
dialog.open();
|
||||
}
|
||||
|
||||
function service_usercertificate_restore(result) {
|
||||
|
||||
var usercertificate = result['usercertificate'];
|
||||
if (!usercertificate) {
|
||||
alert('Service has no usercertificate.');
|
||||
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) {
|
||||
var dialog = certificate_confirmation_dialog({
|
||||
title: 'Success',
|
||||
message: 'Certificate has been restored successfully.'
|
||||
});
|
||||
dialog.open();
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
dialog.open();
|
||||
}
|
||||
|
||||
function service_usercertificate_request(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
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
dialog.open();
|
||||
}
|
||||
|
||||
function service_usercertificate_load(container, dt, result) {
|
||||
|
||||
var krbprincipalname = result['krbprincipalname'][0];
|
||||
|
||||
var table = $('<table/>');
|
||||
|
||||
var tr = $('<tr/>').appendTo(table);
|
||||
|
||||
var 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) {
|
||||
service_usercertificate_get(data.result.result);
|
||||
}
|
||||
);
|
||||
}
|
||||
}).appendTo(td);
|
||||
|
||||
$('<input/>', {
|
||||
type: 'button',
|
||||
value: 'Revoke',
|
||||
click: function() {
|
||||
ipa_cmd('service_show', [krbprincipalname], {},
|
||||
function(data, text_status, xhr) {
|
||||
service_usercertificate_revoke(data.result.result);
|
||||
}
|
||||
);
|
||||
}
|
||||
}).appendTo(td);
|
||||
|
||||
$('<input/>', {
|
||||
type: 'button',
|
||||
value: 'View',
|
||||
click: function() {
|
||||
ipa_cmd('service_show', [krbprincipalname], {},
|
||||
function(data, text_status, xhr) {
|
||||
service_usercertificate_view(data.result.result);
|
||||
}
|
||||
);
|
||||
}
|
||||
}).appendTo(td);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
|
||||
td = $('<td/>').appendTo(tr);
|
||||
td.append('Certificate Revoked:');
|
||||
|
||||
td = $('<td/>').appendTo(tr);
|
||||
$('<input/>', {
|
||||
type: 'button',
|
||||
value: 'Restore',
|
||||
click: function() {
|
||||
ipa_cmd('service_show', [krbprincipalname], {},
|
||||
function(data, text_status, xhr) {
|
||||
service_usercertificate_restore(data.result.result);
|
||||
}
|
||||
);
|
||||
}
|
||||
}).appendTo(td);
|
||||
|
||||
tr = $('<tr/>').appendTo(table);
|
||||
|
||||
td = $('<td/>').appendTo(tr);
|
||||
td.append('No Valid Certificate:');
|
||||
|
||||
td = $('<td/>').appendTo(tr);
|
||||
$('<input/>', {
|
||||
type: 'button',
|
||||
value: 'New Certificate',
|
||||
click: function() {
|
||||
service_usercertificate_request(result);
|
||||
}
|
||||
}).appendTo(td);
|
||||
|
||||
var dd = ipa_create_first_dd(this.name, table);
|
||||
dt.after(dd);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"error": null,
|
||||
"id": 0,
|
||||
"result": {
|
||||
"result": {
|
||||
"unrevoked": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"error": null,
|
||||
"id": 0,
|
||||
"result": {
|
||||
"result": {
|
||||
"certificate": "MIIC2DCCAcCgAwIBAgIBFTANBgkqhkiG9w0BAQsFADAuMQwwCgYDVQQKEwNJUEExHjAcBgNVBAMTFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMDEwMTUwNTE3MzZaFw0xMTA0MTMwNTE3MzZaMCgxDDAKBgNVBAoTA0lQQTEYMBYGA1UEAxMPZGV2LmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDk18o/IK1Qe0Y/eURWsIHcJ/TmGdNy1h2fhzGIILtv8Qgq1K3U4T9eGAZVambpo1SUnJY+k+AAo43TyavSU05se4DIsw00XrrOyD5UunwsW+b+cIUCWbBJLFy9ODsVDJduXrj0RZGHEyta3VuO/gJBtdI9anjVvgegqXUBkenjPwIDAQABo4GKMIGHMB8GA1UdIwQYMBaAFCv9XyGV5ijtHriYMcECVmnNiMMAMD8GCCsGAQUFBwEBBDMwMTAvBggrBgEFBQcwAYYjaHR0cDovL2Rldi5leGFtcGxlLmNvbTo5MTgwL2NhL29jc3AwDgYDVR0PAQH/BAQDAgTwMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQB/OtoBZUYuGD0KZWpNdzIVdCxCTzZAetHA+o97cZCdufiBckZfZ9LEkQdL2MWvcnLlXOnRnQO/BnEAAtYVe4dpmizuzPn1+JTmK9+7q2HhQhXuU2NcsWutgYySNme7eNmfqi8uDoQ8FOPX4LvxLQDyKjkOogs6cEMZePMK8RE60ulHKdYfI23rRNtIExOl1zLJXkpExuXNq1flshyaLLu84B9zwE5FhSD/XAjPyAqYP97IPIkUfWpMyEs3N12JVCVNm0/753CDI946RPnyPpsULZufBV/8sdhDnULHfPIUMPgdOYemm9cYTP/V1uhwwCnFemhSAXSM/g6e9Xm4hH7s",
|
||||
"issuer": "CN=Certificate Authority,O=IPA",
|
||||
"md5_fingerprint": "87:ca:33:52:e3:07:4c:82:76:24:8d:53:ba:da:b3:fe",
|
||||
"request_id": "50",
|
||||
"serial_number": "1",
|
||||
"sha1_fingerprint": "9f:fc:d3:e2:3b:f0:c1:1d:fc:5c:09:fa:f4:10:de:7b:b2:25:ae:7c",
|
||||
"subject": "CN=dev.example.com,O=IPA",
|
||||
"valid_not_after": "Wed Apr 13 05:17:36 2011 UTC",
|
||||
"valid_not_before": "Fri Oct 15 05:17:36 2010 UTC"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"error": null,
|
||||
"id": 0,
|
||||
"result": {
|
||||
"result": {
|
||||
"revoked": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2976,6 +2976,180 @@
|
||||
"query": false,
|
||||
"required": false,
|
||||
"type": "str"
|
||||
},
|
||||
{
|
||||
"attribute": false,
|
||||
"autofill": false,
|
||||
"class": "Str",
|
||||
"cli_name": "issuer",
|
||||
"cli_short_name": null,
|
||||
"default": null,
|
||||
"doc": "Issuer",
|
||||
"exclude": null,
|
||||
"flags": [
|
||||
"no_update",
|
||||
"no_create",
|
||||
"no_search"
|
||||
],
|
||||
"hint": null,
|
||||
"include": null,
|
||||
"label": "Issuer",
|
||||
"length": null,
|
||||
"maxlength": null,
|
||||
"minlength": null,
|
||||
"multivalue": false,
|
||||
"name": "issuer",
|
||||
"pattern": null,
|
||||
"pattern_errmsg": null,
|
||||
"primary_key": false,
|
||||
"query": false,
|
||||
"required": false,
|
||||
"type": "unicode"
|
||||
},
|
||||
{
|
||||
"attribute": false,
|
||||
"autofill": false,
|
||||
"class": "Str",
|
||||
"cli_name": "valid_not_before",
|
||||
"cli_short_name": null,
|
||||
"default": null,
|
||||
"doc": "Not Before",
|
||||
"exclude": null,
|
||||
"flags": [
|
||||
"no_update",
|
||||
"no_create",
|
||||
"no_search"
|
||||
],
|
||||
"hint": null,
|
||||
"include": null,
|
||||
"label": "Not Before",
|
||||
"length": null,
|
||||
"maxlength": null,
|
||||
"minlength": null,
|
||||
"multivalue": false,
|
||||
"name": "valid_not_before",
|
||||
"pattern": null,
|
||||
"pattern_errmsg": null,
|
||||
"primary_key": false,
|
||||
"query": false,
|
||||
"required": false,
|
||||
"type": "unicode"
|
||||
},
|
||||
{
|
||||
"attribute": false,
|
||||
"autofill": false,
|
||||
"class": "Str",
|
||||
"cli_name": "valid_not_after",
|
||||
"cli_short_name": null,
|
||||
"default": null,
|
||||
"doc": "Not After",
|
||||
"exclude": null,
|
||||
"flags": [
|
||||
"no_update",
|
||||
"no_create",
|
||||
"no_search"
|
||||
],
|
||||
"hint": null,
|
||||
"include": null,
|
||||
"label": "Not After",
|
||||
"length": null,
|
||||
"maxlength": null,
|
||||
"minlength": null,
|
||||
"multivalue": false,
|
||||
"name": "valid_not_after",
|
||||
"pattern": null,
|
||||
"pattern_errmsg": null,
|
||||
"primary_key": false,
|
||||
"query": false,
|
||||
"required": false,
|
||||
"type": "unicode"
|
||||
},
|
||||
{
|
||||
"attribute": false,
|
||||
"autofill": false,
|
||||
"class": "Str",
|
||||
"cli_name": "md5_fingerprint",
|
||||
"cli_short_name": null,
|
||||
"default": null,
|
||||
"doc": "Fingerprint (MD5)",
|
||||
"exclude": null,
|
||||
"flags": [
|
||||
"no_update",
|
||||
"no_create",
|
||||
"no_search"
|
||||
],
|
||||
"hint": null,
|
||||
"include": null,
|
||||
"label": "Fingerprint (MD5)",
|
||||
"length": null,
|
||||
"maxlength": null,
|
||||
"minlength": null,
|
||||
"multivalue": false,
|
||||
"name": "md5_fingerprint",
|
||||
"pattern": null,
|
||||
"pattern_errmsg": null,
|
||||
"primary_key": false,
|
||||
"query": false,
|
||||
"required": false,
|
||||
"type": "unicode"
|
||||
},
|
||||
{
|
||||
"attribute": false,
|
||||
"autofill": false,
|
||||
"class": "Str",
|
||||
"cli_name": "sha1_fingerprint",
|
||||
"cli_short_name": null,
|
||||
"default": null,
|
||||
"doc": "Fingerprint (SHA1)",
|
||||
"exclude": null,
|
||||
"flags": [
|
||||
"no_update",
|
||||
"no_create",
|
||||
"no_search"
|
||||
],
|
||||
"hint": null,
|
||||
"include": null,
|
||||
"label": "Fingerprint (SHA1)",
|
||||
"length": null,
|
||||
"maxlength": null,
|
||||
"minlength": null,
|
||||
"multivalue": false,
|
||||
"name": "sha1_fingerprint",
|
||||
"pattern": null,
|
||||
"pattern_errmsg": null,
|
||||
"primary_key": false,
|
||||
"query": false,
|
||||
"required": false,
|
||||
"type": "unicode"
|
||||
},
|
||||
{
|
||||
"attribute": false,
|
||||
"autofill": false,
|
||||
"class": "Str",
|
||||
"cli_name": "serial_number",
|
||||
"cli_short_name": null,
|
||||
"default": null,
|
||||
"doc": "Serial number",
|
||||
"exclude": null,
|
||||
"flags": [
|
||||
"no_update",
|
||||
"no_create",
|
||||
"no_search"
|
||||
],
|
||||
"hint": null,
|
||||
"include": null,
|
||||
"label": "Serial number",
|
||||
"length": null,
|
||||
"maxlength": null,
|
||||
"minlength": null,
|
||||
"multivalue": false,
|
||||
"name": "serial_number",
|
||||
"pattern": null,
|
||||
"pattern_errmsg": null,
|
||||
"primary_key": false,
|
||||
"query": false,
|
||||
"required": false,
|
||||
"type": "unicode"
|
||||
}
|
||||
],
|
||||
"uuid_attribute": "ipauniqueid"
|
||||
@@ -4163,4 +4337,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,17 +5,24 @@
|
||||
"result": {
|
||||
"dn": "krbprincipalname=test/dev.example.com@dev.example.com,cn=services,cn=accounts,dc=dev,dc=example,dc=com",
|
||||
"has_keytab": false,
|
||||
"issuer": "CN=IPA Test Certificate Authority",
|
||||
"krbprincipalname": [
|
||||
"test/dev.example.com@DEV.EXAMPLE.COM"
|
||||
],
|
||||
"managedby_host": [
|
||||
"dev.example.com"
|
||||
],
|
||||
"md5_fingerprint": "08:86:a9:f9:87:af:0d:d7:42:01:e0:5f:12:9b:32:7f",
|
||||
"serial_number": "1052",
|
||||
"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": "test/dev.example.com@DEV.EXAMPLE.COM"
|
||||
|
||||
@@ -76,6 +76,7 @@ from ipalib.plugins.baseldap import *
|
||||
from ipalib import x509
|
||||
from ipalib import _, ngettext
|
||||
from ipalib import util
|
||||
import nss.nss as nss
|
||||
from nss.error import NSPRError
|
||||
|
||||
|
||||
@@ -203,7 +204,7 @@ class service(LDAPObject):
|
||||
cli_name='certificate',
|
||||
label=_('Certificate'),
|
||||
doc=_('Base-64 encoded server certificate'),
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
api.register(service)
|
||||
@@ -357,7 +358,33 @@ class service_show(LDAPRetrieve):
|
||||
"""
|
||||
member_attributes = ['managedby']
|
||||
takes_options = LDAPRetrieve.takes_options
|
||||
has_output_params = LDAPRetrieve.has_output_params + output_params
|
||||
|
||||
has_output_params = LDAPRetrieve.has_output_params + output_params + (
|
||||
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'),
|
||||
)
|
||||
)
|
||||
|
||||
def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
|
||||
if 'krblastpwdchange' in entry_attrs:
|
||||
@@ -367,6 +394,16 @@ class service_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(service_show)
|
||||
|
||||
Reference in New Issue
Block a user