@@ -766,6 +766,7 @@ | |||
<resource file="${basedir}/resources/settings_16x16.png" /> | |||
<resource file="${basedir}/resources/settings_32x32.png" /> | |||
<resource file="${basedir}/resources/search-icon.png" /> | |||
<resource file="${basedir}/resources/mail_16x16.png" /> | |||
<resource file="${basedir}/resources/blank.png" /> | |||
<resource file="${basedir}/resources/bullet_green.png" /> | |||
<resource file="${basedir}/resources/bullet_orange.png" /> |
@@ -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 |
@@ -0,0 +1,58 @@ | |||
/* | |||
* Copyright 2012 gitblit.com. | |||
* | |||
* Licensed under the Apache License, Version 2.0 (the "License"); | |||
* you may not use this file except in compliance with the License. | |||
* You may obtain a copy of the License at | |||
* | |||
* http://www.apache.org/licenses/LICENSE-2.0 | |||
* | |||
* Unless required by applicable law or agreed to in writing, software | |||
* distributed under the License is distributed on an "AS IS" BASIS, | |||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
* See the License for the specific language governing permissions and | |||
* limitations under the License. | |||
*/ | |||
package com.gitblit.authority; | |||
import java.awt.Component; | |||
import java.awt.Cursor; | |||
import java.io.IOException; | |||
import javax.swing.SwingWorker; | |||
public abstract class AuthorityWorker extends SwingWorker<Boolean, Void> { | |||
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() { | |||
} | |||
} |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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(); | |||
@@ -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(); | |||
@@ -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<String>(Arrays.asList(c.getStringList("user", username, "revoked"))); |
@@ -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<UserCertificateModel> { | |||
} | |||
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<UserCertificateModel> { | |||
revoked = new ArrayList<String>(); | |||
} | |||
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) { |
@@ -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()); | |||
} | |||
} | |||
}); |
@@ -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(); | |||
@@ -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; |
@@ -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 | |||
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 |