From e571c4ae9d9883ba4c4a1739dd9948bf096a2cff Mon Sep 17 00:00:00 2001 From: James Moger Date: Mon, 26 Nov 2012 21:31:12 -0500 Subject: [PATCH] More refinements to GCA --- build.xml | 1 + distrib/gitblit.properties | 11 ++ resources/mail_16x16.png | Bin 0 -> 530 bytes .../gitblit/authority/AuthorityWorker.java | 58 ++++++ .../gitblit/authority/GitblitAuthority.java | 176 ++++++++++++------ .../authority/NewClientCertificateDialog.java | 14 +- ...alog.java => NewSSLCertificateDialog.java} | 13 +- .../authority/UserCertificateConfig.java | 1 + .../authority/UserCertificateModel.java | 23 ++- .../authority/UserCertificatePanel.java | 57 ++++-- .../authority/X509CertificateViewer.java | 2 +- src/com/gitblit/utils/X509Utils.java | 18 +- .../gitblit/wicket/GitBlitWebApp.properties | 14 +- 13 files changed, 300 insertions(+), 88 deletions(-) create mode 100644 resources/mail_16x16.png create mode 100644 src/com/gitblit/authority/AuthorityWorker.java rename src/com/gitblit/authority/{NewWebCertificateDialog.java => NewSSLCertificateDialog.java} (88%) diff --git a/build.xml b/build.xml index aa247d39..59d79b5a 100644 --- a/build.xml +++ b/build.xml @@ -766,6 +766,7 @@ + diff --git a/distrib/gitblit.properties b/distrib/gitblit.properties index 9daabde4..65e19ed4 100644 --- a/distrib/gitblit.properties +++ b/distrib/gitblit.properties @@ -1133,6 +1133,17 @@ server.ajpBindInterface = localhost # This is provided for convenience, its probably more secure to set this value # using the --storePassword command line parameter. # +# If you are using the official JRE or JDK from Oracle you may not have the +# JCE Unlimited Strength Jurisdiction Policy files bundled with your JVM. Because +# of this, your store/key password can not exceed 7 characters. If you require +# longer passwords you may need to install the JCE Unlimited Strength Jurisdiction +# Policy files from Oracle. +# +# http://www.oracle.com/technetwork/java/javase/downloads/index.html +# +# Gitblit and the Gitblit Certificate Authority will both indicate if Unlimited +# Strength encryption is available. +# # SINCE 0.5.0 # RESTART REQUIRED server.storePassword = gitblit diff --git a/resources/mail_16x16.png b/resources/mail_16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..832787392dd9531a54636bfe34a830757faad107 GIT binary patch literal 530 zcmV+t0`2{YP)gjnO$$OSu5+~ z?GnX?h=lA4Aw)tUQAmVFq0y*l{09woYO#CvJPuUx9E=pyT_#!F+yaE_A#~L~0z7#IZ8fe)ldA+)52({5L z7I&}FQv-y8c`#; { + + private final Component parent; + + public AuthorityWorker(Component parent) { + this.parent = parent; + parent.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + + @Override + protected Boolean doInBackground() throws IOException { + return doRequest(); + } + + protected void done() { + parent.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + try { + Boolean success = get(); + if (success) { + onSuccess(); + } else { + onFailure(); + } + } catch (Throwable t) { + Utils.showException(parent, t); + } + } + + protected abstract Boolean doRequest() throws IOException; + + protected abstract void onSuccess(); + + protected void onFailure() { + } +} diff --git a/src/com/gitblit/authority/GitblitAuthority.java b/src/com/gitblit/authority/GitblitAuthority.java index 7734a151..846e9424 100644 --- a/src/com/gitblit/authority/GitblitAuthority.java +++ b/src/com/gitblit/authority/GitblitAuthority.java @@ -88,6 +88,7 @@ import com.gitblit.MailExecutor; import com.gitblit.client.HeaderPanel; import com.gitblit.client.Translation; import com.gitblit.models.UserModel; +import com.gitblit.utils.ArrayUtils; import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; import com.gitblit.utils.X509Utils; @@ -364,7 +365,10 @@ public class GitblitAuthority extends JFrame implements X509Log { public void newCertificate(UserCertificateModel ucm, X509Metadata metadata, boolean sendEmail) { prepareX509Infrastructure(); Date notAfter = metadata.notAfter; - metadata.serverHostname = gitblitSettings.getString(Keys.web.siteName, "localhost"); + metadata.serverHostname = gitblitSettings.getString(Keys.web.siteName, Constants.NAME); + if (StringUtils.isEmpty(metadata.serverHostname)) { + metadata.serverHostname = Constants.NAME; + } UserModel user = ucm.user; // set default values from config file @@ -421,38 +425,7 @@ public class GitblitAuthority extends JFrame implements X509Log { table.getSelectionModel().setSelectionInterval(modelIndex, modelIndex); if (sendEmail) { - // send email - try { - if (mail.isReady()) { - Message message = mail.createMessage(user.emailAddress); - message.setSubject("Your Gitblit client certificate for " + metadata.serverHostname); - - // body of email - String body = X509Utils.processTemplate(new File(caKeystoreFile.getParentFile(), "mail.tmpl"), metadata); - if (StringUtils.isEmpty(body)) { - body = MessageFormat.format("Hi {0}\n\nHere is your client certificate bundle.\nInside the zip file are installation instructions.", user.getDisplayName()); - } - Multipart mp = new MimeMultipart(); - MimeBodyPart messagePart = new MimeBodyPart(); - messagePart.setText(body); - mp.addBodyPart(messagePart); - - // attach zip - MimeBodyPart filePart = new MimeBodyPart(); - FileDataSource fds = new FileDataSource(zip); - filePart.setDataHandler(new DataHandler(fds)); - filePart.setFileName(fds.getName()); - mp.addBodyPart(filePart); - - message.setContent(mp); - - mail.sendNow(message); - } else { - JOptionPane.showMessageDialog(GitblitAuthority.this, "Sorry, the mail server settings are not configured properly.\nCan not send email.", Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE); - } - } catch (Exception e) { - Utils.showException(GitblitAuthority.this, e); - } + sendEmail(user, metadata, zip); } } @@ -527,7 +500,7 @@ public class GitblitAuthority extends JFrame implements X509Log { certificateDefaultsButton = new JButton(new ImageIcon(getClass().getResource("/settings_16x16.png"))); certificateDefaultsButton.setFocusable(false); - certificateDefaultsButton.setToolTipText(Translation.get("gb.certificateDefaults")); + certificateDefaultsButton.setToolTipText(Translation.get("gb.newCertificateDefaults")); certificateDefaultsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -570,7 +543,7 @@ public class GitblitAuthority extends JFrame implements X509Log { panel.add(oids, BorderLayout.CENTER); int result = JOptionPane.showConfirmDialog(GitblitAuthority.this, - panel, Translation.get("gb.certificateDefaults"), JOptionPane.OK_CANCEL_OPTION, + panel, Translation.get("gb.newCertificateDefaults"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, new ImageIcon(getClass().getResource("/settings_32x32.png"))); if (result == JOptionPane.OK_OPTION) { try { @@ -587,33 +560,94 @@ public class GitblitAuthority extends JFrame implements X509Log { } }); - JButton newWebCertificate = new JButton(new ImageIcon(getClass().getResource("/rosette_16x16.png"))); - newWebCertificate.setFocusable(false); - newWebCertificate.setToolTipText(Translation.get("gb.newWebCertificate")); - newWebCertificate.addActionListener(new ActionListener() { + JButton newSSLCertificate = new JButton(new ImageIcon(getClass().getResource("/rosette_16x16.png"))); + newSSLCertificate.setFocusable(false); + newSSLCertificate.setToolTipText(Translation.get("gb.newSSLCertificate")); + newSSLCertificate.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Date defaultExpiration = new Date(System.currentTimeMillis() + 10*TimeUtils.ONEYEAR); - NewWebCertificateDialog dialog = new NewWebCertificateDialog(GitblitAuthority.this, defaultExpiration); + NewSSLCertificateDialog dialog = new NewSSLCertificateDialog(GitblitAuthority.this, defaultExpiration); dialog.setModal(true); dialog.setVisible(true); if (dialog.isCanceled()) { return; } - prepareX509Infrastructure(); - Date expires = dialog.getExpiration(); - String hostname = dialog.getHostname(); + final Date expires = dialog.getExpiration(); + final String hostname = dialog.getHostname(); + + AuthorityWorker worker = new AuthorityWorker(GitblitAuthority.this) { + + @Override + protected Boolean doRequest() throws IOException { + prepareX509Infrastructure(); + + // read CA private key and certificate + File caKeystoreFile = new File(folder, X509Utils.CA_KEY_STORE); + PrivateKey caPrivateKey = X509Utils.getPrivateKey(X509Utils.CA_ALIAS, caKeystoreFile, caKeystorePassword); + X509Certificate caCert = X509Utils.getCertificate(X509Utils.CA_ALIAS, caKeystoreFile, caKeystorePassword); + + // generate new SSL certificate + X509Metadata metadata = new X509Metadata(hostname, caKeystorePassword); + metadata.notAfter = expires; + File serverKeystoreFile = new File(folder, X509Utils.SERVER_KEY_STORE); + X509Certificate cert = X509Utils.newSSLCertificate(metadata, caPrivateKey, caCert, serverKeystoreFile, GitblitAuthority.this); + return cert != null; + } + + @Override + protected void onSuccess() { + JOptionPane.showMessageDialog(GitblitAuthority.this, + MessageFormat.format(Translation.get("gb.sslCertificateGenerated"), hostname), + Translation.get("gb.newSSLCertificate"), JOptionPane.INFORMATION_MESSAGE); + } + }; - // read CA private key and certificate - File caKeystoreFile = new File(folder, X509Utils.CA_KEY_STORE); - PrivateKey caPrivateKey = X509Utils.getPrivateKey(X509Utils.CA_ALIAS, caKeystoreFile, caKeystorePassword); - X509Certificate caCert = X509Utils.getCertificate(X509Utils.CA_ALIAS, caKeystoreFile, caKeystorePassword); + worker.execute(); + } + }); + + JButton emailBundle = new JButton(new ImageIcon(getClass().getResource("/mail_16x16.png"))); + emailBundle.setFocusable(false); + emailBundle.setToolTipText(Translation.get("gb.emailCertificateBundle")); + emailBundle.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + int row = table.getSelectedRow(); + if (row < 0) { + return; + } + int modelIndex = table.convertRowIndexToModel(row); + final UserCertificateModel ucm = tableModel.get(modelIndex); + if (ArrayUtils.isEmpty(ucm.certs)) { + JOptionPane.showMessageDialog(GitblitAuthority.this, MessageFormat.format(Translation.get("gb.pleaseGenerateClientCertificate"), ucm.user.getDisplayName())); + } + final File zip = new File(folder, X509Utils.CERTS + File.separator + ucm.user.username + File.separator + ucm.user.username + ".zip"); + if (!zip.exists()) { + return; + } - // generate new SSL certificate - X509Metadata metadata = new X509Metadata(hostname, caKeystorePassword); - metadata.notAfter = expires; - File serverKeystoreFile = new File(folder, X509Utils.SERVER_KEY_STORE); - X509Utils.newSSLCertificate(metadata, caPrivateKey, caCert, serverKeystoreFile, GitblitAuthority.this); + AuthorityWorker worker = new AuthorityWorker(GitblitAuthority.this) { + @Override + protected Boolean doRequest() throws IOException { + X509Metadata metadata = new X509Metadata(ucm.user.username, "whocares"); + metadata.serverHostname = gitblitSettings.getString(Keys.web.siteName, Constants.NAME); + if (StringUtils.isEmpty(metadata.serverHostname)) { + metadata.serverHostname = Constants.NAME; + } + metadata.userDisplayname = ucm.user.getDisplayName(); + sendEmail(ucm.user, metadata, zip); + return true; + } + + @Override + protected void onSuccess() { + JOptionPane.showMessageDialog(GitblitAuthority.this, MessageFormat.format(Translation.get("gb.clientCertificateBundleSent"), + ucm.user.getDisplayName())); + } + + }; + worker.execute(); } }); @@ -631,7 +665,8 @@ public class GitblitAuthority extends JFrame implements X509Log { JPanel buttonControls = new JPanel(new FlowLayout(FlowLayout.LEFT, Utils.MARGIN, Utils.MARGIN)); buttonControls.add(certificateDefaultsButton); - buttonControls.add(newWebCertificate); + buttonControls.add(newSSLCertificate); + buttonControls.add(emailBundle); JPanel userControls = new JPanel(new FlowLayout(FlowLayout.RIGHT, Utils.MARGIN, Utils.MARGIN)); userControls.add(new JLabel(Translation.get("gb.filter"))); @@ -708,4 +743,39 @@ public class GitblitAuthority extends JFrame implements X509Log { } } } + + private void sendEmail(UserModel user, X509Metadata metadata, File zip) { + // send email + try { + if (mail.isReady()) { + Message message = mail.createMessage(user.emailAddress); + message.setSubject("Your Gitblit client certificate for " + metadata.serverHostname); + + // body of email + String body = X509Utils.processTemplate(new File(folder, X509Utils.CERTS + File.separator + "mail.tmpl"), metadata); + if (StringUtils.isEmpty(body)) { + body = MessageFormat.format("Hi {0}\n\nHere is your client certificate bundle.\nInside the zip file are installation instructions.", user.getDisplayName()); + } + Multipart mp = new MimeMultipart(); + MimeBodyPart messagePart = new MimeBodyPart(); + messagePart.setText(body); + mp.addBodyPart(messagePart); + + // attach zip + MimeBodyPart filePart = new MimeBodyPart(); + FileDataSource fds = new FileDataSource(zip); + filePart.setDataHandler(new DataHandler(fds)); + filePart.setFileName(fds.getName()); + mp.addBodyPart(filePart); + + message.setContent(mp); + + mail.sendNow(message); + } else { + JOptionPane.showMessageDialog(GitblitAuthority.this, "Sorry, the mail server settings are not configured properly.\nCan not send email.", Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE); + } + } catch (Exception e) { + Utils.showException(GitblitAuthority.this, e); + } + } } diff --git a/src/com/gitblit/authority/NewClientCertificateDialog.java b/src/com/gitblit/authority/NewClientCertificateDialog.java index b04ae73c..35fac5ae 100644 --- a/src/com/gitblit/authority/NewClientCertificateDialog.java +++ b/src/com/gitblit/authority/NewClientCertificateDialog.java @@ -16,6 +16,7 @@ package com.gitblit.authority; import java.awt.BorderLayout; +import java.awt.Dimension; import java.awt.Frame; import java.awt.GridLayout; import java.awt.Insets; @@ -30,6 +31,8 @@ import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; import javax.swing.JTextField; import org.bouncycastle.util.Arrays; @@ -64,7 +67,6 @@ public class NewClientCertificateDialog extends JDialog { return Utils.INSETS; } }; - content.add(new HeaderPanel(Translation.get("gb.newCertificate") + " (" + displayname + ")", "rosette_16x16.png"), BorderLayout.NORTH); expirationDate = new JDateChooser(defaultExpiration); pw1 = new JPasswordField(20); @@ -91,7 +93,6 @@ public class NewClientCertificateDialog extends JDialog { panel.add(sendEmail); } - content.add(panel, BorderLayout.CENTER); JButton ok = new JButton(Translation.get("gb.ok")); ok.addActionListener(new ActionListener() { @@ -114,8 +115,17 @@ public class NewClientCertificateDialog extends JDialog { controls.add(ok); controls.add(cancel); + JTextArea message = new JTextArea(Translation.get("gb.newClientCertificateMessage")); + message.setLineWrap(true); + message.setWrapStyleWord(true); + message.setEditable(false); + message.setPreferredSize(new Dimension(300, 100)); + + content.add(new JScrollPane(message), BorderLayout.CENTER); + content.add(panel, BorderLayout.NORTH); content.add(controls, BorderLayout.SOUTH); + getContentPane().add(new HeaderPanel(Translation.get("gb.newCertificate") + " (" + displayname + ")", "rosette_16x16.png"), BorderLayout.NORTH); getContentPane().add(content, BorderLayout.CENTER); pack(); diff --git a/src/com/gitblit/authority/NewWebCertificateDialog.java b/src/com/gitblit/authority/NewSSLCertificateDialog.java similarity index 88% rename from src/com/gitblit/authority/NewWebCertificateDialog.java rename to src/com/gitblit/authority/NewSSLCertificateDialog.java index a6846c57..1ff542a2 100644 --- a/src/com/gitblit/authority/NewWebCertificateDialog.java +++ b/src/com/gitblit/authority/NewSSLCertificateDialog.java @@ -35,7 +35,7 @@ import com.gitblit.client.Translation; import com.gitblit.utils.StringUtils; import com.toedter.calendar.JDateChooser; -public class NewWebCertificateDialog extends JDialog { +public class NewSSLCertificateDialog extends JDialog { private static final long serialVersionUID = 1L; @@ -43,10 +43,10 @@ public class NewWebCertificateDialog extends JDialog { JTextField hostname; boolean isCanceled = true; - public NewWebCertificateDialog(Frame owner, Date defaultExpiration) { + public NewSSLCertificateDialog(Frame owner, Date defaultExpiration) { super(owner); - setTitle(Translation.get("gb.newWebCertificate")); + setTitle(Translation.get("gb.newSSLCertificate")); JPanel content = new JPanel(new BorderLayout(Utils.MARGIN, Utils.MARGIN)) { private static final long serialVersionUID = 1L; @@ -57,7 +57,6 @@ public class NewWebCertificateDialog extends JDialog { return Utils.INSETS; } }; - content.add(new HeaderPanel(Translation.get("gb.newWebCertificate"), "rosette_16x16.png"), BorderLayout.NORTH); expirationDate = new JDateChooser(defaultExpiration); hostname = new JTextField(20); @@ -69,8 +68,6 @@ public class NewWebCertificateDialog extends JDialog { panel.add(new JLabel(Translation.get("gb.expires"))); panel.add(expirationDate); - - content.add(panel, BorderLayout.CENTER); JButton ok = new JButton(Translation.get("gb.ok")); ok.addActionListener(new ActionListener() { @@ -92,9 +89,11 @@ public class NewWebCertificateDialog extends JDialog { JPanel controls = new JPanel(); controls.add(ok); controls.add(cancel); - + + content.add(panel, BorderLayout.CENTER); content.add(controls, BorderLayout.SOUTH); + getContentPane().add(new HeaderPanel(Translation.get("gb.newSSLCertificate"), "rosette_16x16.png"), BorderLayout.NORTH); getContentPane().add(content, BorderLayout.CENTER); pack(); diff --git a/src/com/gitblit/authority/UserCertificateConfig.java b/src/com/gitblit/authority/UserCertificateConfig.java index 47132a06..5ec76f77 100644 --- a/src/com/gitblit/authority/UserCertificateConfig.java +++ b/src/com/gitblit/authority/UserCertificateConfig.java @@ -51,6 +51,7 @@ public class UserCertificateConfig { uc.expires = df.parse(c.getString("user", username, "expires")); } catch (ParseException e) { LoggerFactory.getLogger(UserCertificateConfig.class).error("Failed to parse date!", e); + } catch (NullPointerException e) { } uc.notes = c.getString("user", username, "notes"); uc.revoked = new ArrayList(Arrays.asList(c.getStringList("user", username, "revoked"))); diff --git a/src/com/gitblit/authority/UserCertificateModel.java b/src/com/gitblit/authority/UserCertificateModel.java index f5d71bb0..6c69a93b 100644 --- a/src/com/gitblit/authority/UserCertificateModel.java +++ b/src/com/gitblit/authority/UserCertificateModel.java @@ -27,6 +27,7 @@ import org.eclipse.jgit.lib.Config; import com.gitblit.Constants; import com.gitblit.models.UserModel; import com.gitblit.utils.ArrayUtils; +import com.gitblit.utils.StringUtils; import com.gitblit.utils.TimeUtils; import com.gitblit.utils.X509Utils.RevocationReason; @@ -42,14 +43,20 @@ public class UserCertificateModel implements Comparable { } public void update(Config config) { - if (expires != null) { + if (expires == null) { + config.unset("user", user.username, "expires"); + } else { SimpleDateFormat df = new SimpleDateFormat(Constants.ISO8601); config.setString("user", user.username, "expires", df.format(expires)); } - if (notes != null) { + if (StringUtils.isEmpty(notes)) { + config.unset("user", user.username, "notes"); + } else { config.setString("user", user.username, "notes", notes); } - if (!ArrayUtils.isEmpty(revoked)) { + if (ArrayUtils.isEmpty(revoked)) { + config.unset("user", user.username, "revoked"); + } else { config.setStringList("user", user.username, "revoked", revoked); } } @@ -64,6 +71,16 @@ public class UserCertificateModel implements Comparable { revoked = new ArrayList(); } revoked.add(serial.toString() + ":" + reason.ordinal()); + expires = null; + for (X509Certificate cert : certs) { + if (!isRevoked(cert.getSerialNumber())) { + if (!isExpired(cert.getNotAfter())) { + if (expires == null || cert.getNotAfter().after(expires)) { + expires = cert.getNotAfter(); + } + } + } + } } public boolean isRevoked(BigInteger serial) { diff --git a/src/com/gitblit/authority/UserCertificatePanel.java b/src/com/gitblit/authority/UserCertificatePanel.java index 79c0d940..8a60f47e 100644 --- a/src/com/gitblit/authority/UserCertificatePanel.java +++ b/src/com/gitblit/authority/UserCertificatePanel.java @@ -16,14 +16,15 @@ package com.gitblit.authority; import java.awt.BorderLayout; -import java.awt.Cursor; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.io.IOException; import java.security.cert.X509Certificate; +import java.text.MessageFormat; import java.util.Date; import javax.swing.ImageIcon; @@ -156,20 +157,32 @@ public abstract class UserCertificatePanel extends JPanel { if (dialog.isCanceled()) { return; } - - setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - UserModel user = ucm.user; - X509Metadata metadata = new X509Metadata(user.username, dialog.getPassword()); + + final boolean sendEmail = dialog.sendEmail(); + final UserModel user = ucm.user; + final X509Metadata metadata = new X509Metadata(user.username, dialog.getPassword()); metadata.userDisplayname = user.getDisplayName(); metadata.emailAddress = user.emailAddress; metadata.passwordHint = dialog.getPasswordHint(); metadata.notAfter = dialog.getExpiration(); - newCertificate(ucm, metadata, dialog.sendEmail()); + AuthorityWorker worker = new AuthorityWorker(UserCertificatePanel.this.owner) { + @Override + protected Boolean doRequest() throws IOException { + newCertificate(ucm, metadata, sendEmail); + return true; + } + + @Override + protected void onSuccess() { + JOptionPane.showMessageDialog(UserCertificatePanel.this.owner, + MessageFormat.format(Translation.get("gb.clientCertificateGenerated"), user.getDisplayName()), + Translation.get("gb.newCertificate"), JOptionPane.INFORMATION_MESSAGE); + } + }; + worker.execute(); } catch (Exception x) { Utils.showException(UserCertificatePanel.this, x); - } finally { - setCursor(Cursor.getDefaultCursor()); } } }); @@ -184,7 +197,7 @@ public abstract class UserCertificatePanel extends JPanel { return; } int modelIndex = table.convertRowIndexToModel(row); - X509Certificate cert = tableModel.get(modelIndex); + final X509Certificate cert = tableModel.get(modelIndex); String [] choices = new String[RevocationReason.reasons.length]; for (int i = 0; i < choices.length; i++) { @@ -197,13 +210,14 @@ public abstract class UserCertificatePanel extends JPanel { if (choice == null) { return; } - RevocationReason reason = RevocationReason.unspecified; + RevocationReason selection = RevocationReason.unspecified; for (int i = 0 ; i < choices.length; i++) { if (choices[i].equals(choice)) { - reason = RevocationReason.reasons[i]; + selection = RevocationReason.reasons[i]; break; } } + final RevocationReason reason = selection; if (!ucm.isRevoked(cert.getSerialNumber())) { if (ucm.certs.size() == 1) { // no other certificates @@ -222,12 +236,27 @@ public abstract class UserCertificatePanel extends JPanel { } ucm.expires = newExpires; } - revoke(ucm, cert, reason); + + AuthorityWorker worker = new AuthorityWorker(UserCertificatePanel.this.owner) { + + @Override + protected Boolean doRequest() throws IOException { + revoke(ucm, cert, reason); + return true; + } + + @Override + protected void onSuccess() { + JOptionPane.showMessageDialog(UserCertificatePanel.this.owner, + MessageFormat.format(Translation.get("gb.certificateRevoked"), cert.getSerialNumber(), cert.getIssuerDN().getName()), + Translation.get("gb.revokeCertificate"), JOptionPane.INFORMATION_MESSAGE); + } + + }; + worker.execute(); } } catch (Exception x) { Utils.showException(UserCertificatePanel.this, x); - } finally { - setCursor(Cursor.getDefaultCursor()); } } }); diff --git a/src/com/gitblit/authority/X509CertificateViewer.java b/src/com/gitblit/authority/X509CertificateViewer.java index 1b095153..797b9a81 100644 --- a/src/com/gitblit/authority/X509CertificateViewer.java +++ b/src/com/gitblit/authority/X509CertificateViewer.java @@ -56,7 +56,6 @@ public class X509CertificateViewer extends JDialog { return Utils.INSETS; } }; - content.add(new HeaderPanel("certificiate", "rosette_16x16.png"), BorderLayout.NORTH); DateFormat df = DateFormat.getDateTimeInstance(); @@ -96,6 +95,7 @@ public class X509CertificateViewer extends JDialog { content.add(controls, BorderLayout.SOUTH); + getContentPane().add(new HeaderPanel(Translation.get("gb.certificate"), "rosette_16x16.png"), BorderLayout.NORTH); getContentPane().add(content, BorderLayout.CENTER); pack(); diff --git a/src/com/gitblit/utils/X509Utils.java b/src/com/gitblit/utils/X509Utils.java index 1510b2cf..24afb8d9 100644 --- a/src/com/gitblit/utils/X509Utils.java +++ b/src/com/gitblit/utils/X509Utils.java @@ -561,7 +561,7 @@ public class X509Utils { new Certificate[] { cert, caCert }); saveKeyStore(targetStoreFile, serverStore, sslMetadata.password); - x509log.log(MessageFormat.format("New web certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getSubjectDN().getName())); + x509log.log(MessageFormat.format("New SSL certificate {0,number,0} [{1}]", cert.getSerialNumber(), cert.getSubjectDN().getName())); return cert; } catch (Throwable t) { throw new RuntimeException("Failed to generate SSL certificate!", t); @@ -935,10 +935,18 @@ public class X509Utils { String message = FileUtils.readContent(template, "\n"); if (!StringUtils.isEmpty(message)) { content = message; - content = content.replace("$serverHostname", metadata.serverHostname); - content = content.replace("$username", metadata.commonName); - content = content.replace("$userDisplayname", metadata.userDisplayname); - content = content.replace("$storePasswordHint", metadata.passwordHint); + if (!StringUtils.isEmpty(metadata.serverHostname)) { + content = content.replace("$serverHostname", metadata.serverHostname); + } + if (!StringUtils.isEmpty(metadata.commonName)) { + content = content.replace("$username", metadata.commonName); + } + if (!StringUtils.isEmpty(metadata.userDisplayname)) { + content = content.replace("$userDisplayname", metadata.userDisplayname); + } + if (!StringUtils.isEmpty(metadata.passwordHint)) { + content = content.replace("$storePasswordHint", metadata.passwordHint); + } } } return content; diff --git a/src/com/gitblit/wicket/GitBlitWebApp.properties b/src/com/gitblit/wicket/GitBlitWebApp.properties index 1a1ee175..2de266e9 100644 --- a/src/com/gitblit/wicket/GitBlitWebApp.properties +++ b/src/com/gitblit/wicket/GitBlitWebApp.properties @@ -417,6 +417,14 @@ gb.time.inHours = in {0} hours gb.time.inDays = in {0} days gb.hostname = hostname gb.hostnameRequired = Please enter a hostname -gb.newWebCertificate = new server SSL certificate -gb.certificateDefaults = certificate defaults -gb.duration = duration \ No newline at end of file +gb.newSSLCertificate = new server SSL certificate +gb.newCertificateDefaults = new certificate defaults +gb.duration = duration +gb.certificateRevoked = Certificate {0,number,0} has been revoked +gb.clientCertificateGenerated = Successfully generated new client certificate for {0} +gb.sslCertificateGenerated = Successfully generated new server SSL certificate for {0} +gb.newClientCertificateMessage = NOTE:\nThe 'password' is not the user's password, it is the password to protect the user's keystore. This password is not saved so you must also enter a 'hint' which will be included in the user's README instructions. +gb.certificate = certificate +gb.emailCertificateBundle = email client certificate bundle +gb.pleaseGenerateClientCertificate = Please generate a client certificate for {0} +gb.clientCertificateBundleSent = Client certificate bundle for {0} sent \ No newline at end of file -- 2.39.5