Fix 3315942, merge patch provided by Jeremiah Albrant: Ask user to select client certificate

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1715 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2011-06-23 22:01:06 +00:00
parent c85225384b
commit 7fef14109f
4 changed files with 510 additions and 217 deletions

View File

@ -86,6 +86,13 @@
<role>Java Contributor</role> <role>Java Contributor</role>
</roles> </roles>
</contributor> </contributor>
<contributor>
<name>Jeremiah Albrant</name>
<url>http://sourceforge.net/users/?user_id=2903536</url>
<roles>
<role>Java Contributor</role>
</roles>
</contributor>
<contributor> <contributor>
<name>Henning Holtschneider</name> <name>Henning Holtschneider</name>
<email>hehol@users.sourceforge.net</email> <email>hehol@users.sourceforge.net</email>
@ -225,7 +232,7 @@
<dependency> <dependency>
<groupId>org.eclipse</groupId> <groupId>org.eclipse</groupId>
<artifactId>swt</artifactId> <artifactId>swt</artifactId>
<version>3.6.0</version> <version>3.7.0</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -1,216 +1,226 @@
/* /*
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
* Copyright (C) 2009 Mickael Guessant * Copyright (C) 2009 Mickael Guessant
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
package davmail.http; package davmail.http;
import davmail.BundleMessage; import davmail.BundleMessage;
import davmail.Settings; import davmail.Settings;
import davmail.ui.PasswordPromptDialog; import davmail.ui.PasswordPromptDialog;
import davmail.ui.tray.DavGatewayTray; import davmail.ui.tray.DavGatewayTray;
import org.apache.commons.httpclient.HttpsURL; import org.apache.commons.httpclient.HttpsURL;
import org.apache.commons.httpclient.params.HttpConnectionParams; import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import javax.net.ssl.*; import javax.net.ssl.*;
import javax.security.auth.callback.Callback; import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.callback.UnsupportedCallbackException;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.Socket; import java.net.Socket;
import java.net.URL; import java.net.URL;
import java.security.*; import java.security.*;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
* Manual Socket Factory. * Manual Socket Factory.
* Let user choose to accept or reject certificate * Let user choose to accept or reject certificate
*/ */
public class DavGatewaySSLProtocolSocketFactory implements SecureProtocolSocketFactory { public class DavGatewaySSLProtocolSocketFactory implements SecureProtocolSocketFactory {
/** /**
* Register custom Socket Factory to let user accept or reject certificate * Register custom Socket Factory to let user accept or reject certificate
*/ */
public static void register() { public static void register() {
String urlString = Settings.getProperty("davmail.url"); String urlString = Settings.getProperty("davmail.url");
try { try {
URL url = new URL(urlString); URL url = new URL(urlString);
String protocol = url.getProtocol(); String protocol = url.getProtocol();
if ("https".equals(protocol)) { if ("https".equals(protocol)) {
int port = url.getPort(); int port = url.getPort();
if (port < 0) { if (port < 0) {
port = HttpsURL.DEFAULT_PORT; port = HttpsURL.DEFAULT_PORT;
} }
Protocol.registerProtocol(url.getProtocol(), Protocol.registerProtocol(url.getProtocol(),
new Protocol(protocol, (ProtocolSocketFactory) new DavGatewaySSLProtocolSocketFactory(), port)); new Protocol(protocol, (ProtocolSocketFactory) new DavGatewaySSLProtocolSocketFactory(), port));
} }
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
DavGatewayTray.error(new BundleMessage("LOG_INVALID_URL", urlString)); DavGatewayTray.error(new BundleMessage("LOG_INVALID_URL", urlString));
} }
} }
private KeyStore.ProtectionParameter getProtectionParameter(String password) { private KeyStore.ProtectionParameter getProtectionParameter(String password) {
if (password != null && password.length() > 0) { if (password != null && password.length() > 0) {
// password provided: create a PasswordProtection // password provided: create a PasswordProtection
return new KeyStore.PasswordProtection(password.toCharArray()); return new KeyStore.PasswordProtection(password.toCharArray());
} else { } else {
// request password at runtime through a callback // request password at runtime through a callback
return new KeyStore.CallbackHandlerProtection(new CallbackHandler() { return new KeyStore.CallbackHandlerProtection(new CallbackHandler() {
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
if (callbacks.length > 0 && callbacks[0] instanceof PasswordCallback) { if (callbacks.length > 0 && callbacks[0] instanceof PasswordCallback) {
PasswordPromptDialog passwordPromptDialog = new PasswordPromptDialog(((PasswordCallback) callbacks[0]).getPrompt()); PasswordPromptDialog passwordPromptDialog = new PasswordPromptDialog(((PasswordCallback) callbacks[0]).getPrompt());
((PasswordCallback) callbacks[0]).setPassword(passwordPromptDialog.getPassword()); ((PasswordCallback) callbacks[0]).setPassword(passwordPromptDialog.getPassword());
} }
} }
}); });
} }
} }
private SSLContext sslcontext; private SSLContext sslcontext;
private SSLContext createSSLContext() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, KeyManagementException, KeyStoreException { private SSLContext createSSLContext() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, KeyManagementException, KeyStoreException {
// PKCS11 client certificate settings // PKCS11 client certificate settings
String pkcs11Library = Settings.getProperty("davmail.ssl.pkcs11Library"); String pkcs11Library = Settings.getProperty("davmail.ssl.pkcs11Library");
String clientKeystoreType = Settings.getProperty("davmail.ssl.clientKeystoreType"); String clientKeystoreType = Settings.getProperty("davmail.ssl.clientKeystoreType");
// set default keystore type // set default keystore type
if (clientKeystoreType == null || clientKeystoreType.length() == 0) { if (clientKeystoreType == null || clientKeystoreType.length() == 0) {
clientKeystoreType = "PKCS11"; clientKeystoreType = "PKCS11";
} }
if (pkcs11Library != null && pkcs11Library.length() > 0 && "PKCS11".equals(clientKeystoreType)) { if (pkcs11Library != null && pkcs11Library.length() > 0 && "PKCS11".equals(clientKeystoreType)) {
StringBuilder pkcs11Buffer = new StringBuilder(); StringBuilder pkcs11Buffer = new StringBuilder();
pkcs11Buffer.append("name=DavMail\n"); pkcs11Buffer.append("name=DavMail\n");
pkcs11Buffer.append("library=").append(pkcs11Library).append('\n'); pkcs11Buffer.append("library=").append(pkcs11Library).append('\n');
String pkcs11Config = Settings.getProperty("davmail.ssl.pkcs11Config"); String pkcs11Config = Settings.getProperty("davmail.ssl.pkcs11Config");
if (pkcs11Config != null && pkcs11Config.length() > 0) { if (pkcs11Config != null && pkcs11Config.length() > 0) {
pkcs11Buffer.append(pkcs11Config).append('\n'); pkcs11Buffer.append(pkcs11Config).append('\n');
} }
SunPKCS11ProviderHandler.registerProvider(pkcs11Buffer.toString()); SunPKCS11ProviderHandler.registerProvider(pkcs11Buffer.toString());
} }
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(/*KeyManagerFactory.getDefaultAlgorithm()*/"NewSunX509"); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(/*KeyManagerFactory.getDefaultAlgorithm()*/"NewSunX509");
ArrayList<KeyStore.Builder> keyStoreBuilders = new ArrayList<KeyStore.Builder>(); ArrayList<KeyStore.Builder> keyStoreBuilders = new ArrayList<KeyStore.Builder>();
// PKCS11 (smartcard) keystore with password callback // PKCS11 (smartcard) keystore with password callback
KeyStore.Builder scBuilder = KeyStore.Builder.newInstance("PKCS11", null, getProtectionParameter(null)); KeyStore.Builder scBuilder = KeyStore.Builder.newInstance("PKCS11", null, getProtectionParameter(null));
keyStoreBuilders.add(scBuilder); keyStoreBuilders.add(scBuilder);
String clientKeystoreFile = Settings.getProperty("davmail.ssl.clientKeystoreFile"); String clientKeystoreFile = Settings.getProperty("davmail.ssl.clientKeystoreFile");
String clientKeystorePass = Settings.getProperty("davmail.ssl.clientKeystorePass"); String clientKeystorePass = Settings.getProperty("davmail.ssl.clientKeystorePass");
if (clientKeystoreFile != null && clientKeystoreFile.length() > 0 if (clientKeystoreFile != null && clientKeystoreFile.length() > 0
&& ("PKCS12".equals(clientKeystoreType) || "JKS".equals(clientKeystoreType))) { && ("PKCS12".equals(clientKeystoreType) || "JKS".equals(clientKeystoreType))) {
// PKCS12 file based keystore // PKCS12 file based keystore
KeyStore.Builder fsBuilder = KeyStore.Builder.newInstance(clientKeystoreType, null, KeyStore.Builder fsBuilder = KeyStore.Builder.newInstance(clientKeystoreType, null,
new File(clientKeystoreFile), getProtectionParameter(clientKeystorePass)); new File(clientKeystoreFile), getProtectionParameter(clientKeystorePass));
keyStoreBuilders.add(fsBuilder); keyStoreBuilders.add(fsBuilder);
} }
ManagerFactoryParameters keyStoreBuilderParameters = new KeyStoreBuilderParameters(keyStoreBuilders); ManagerFactoryParameters keyStoreBuilderParameters = new KeyStoreBuilderParameters(keyStoreBuilders);
keyManagerFactory.init(keyStoreBuilderParameters); keyManagerFactory.init(keyStoreBuilderParameters);
SSLContext context = SSLContext.getInstance("SSL"); // Get a list of key managers
context.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{new DavGatewayX509TrustManager()}, null); KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
return context;
} // Walk through the key managers and replace all X509 Key Managers with
// a specialized wrapped DavMail X509 Key Manager
private SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, InvalidAlgorithmParameterException { for (int i = 0; i < keyManagers.length; i++) {
if (this.sslcontext == null) { KeyManager keyManager = keyManagers[i];
this.sslcontext = createSSLContext(); if (keyManager instanceof X509KeyManager) {
} keyManagers[i] = new DavMailX509KeyManager((X509KeyManager) keyManager);
return this.sslcontext; }
} }
SSLContext context = SSLContext.getInstance("SSL");
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException { context.init(keyManagers, new TrustManager[]{new DavGatewayX509TrustManager()}, null);
try { return context;
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); }
} catch (NoSuchAlgorithmException e) {
throw new IOException(e + " " + e.getMessage()); private SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, InvalidAlgorithmParameterException {
} catch (KeyManagementException e) { if (this.sslcontext == null) {
throw new IOException(e + " " + e.getMessage()); this.sslcontext = createSSLContext();
} catch (KeyStoreException e) { }
throw new IOException(e + " " + e.getMessage()); return this.sslcontext;
} catch (InvalidAlgorithmParameterException e) { }
throw new IOException(e + " " + e.getMessage());
} public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) throws IOException {
} try {
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort, HttpConnectionParams params) throws IOException { } catch (NoSuchAlgorithmException e) {
try { throw new IOException(e + " " + e.getMessage());
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); } catch (KeyManagementException e) {
} catch (NoSuchAlgorithmException e) { throw new IOException(e + " " + e.getMessage());
throw new IOException(e + " " + e.getMessage()); } catch (KeyStoreException e) {
} catch (KeyManagementException e) { throw new IOException(e + " " + e.getMessage());
throw new IOException(e + " " + e.getMessage()); } catch (InvalidAlgorithmParameterException e) {
} catch (KeyStoreException e) { throw new IOException(e + " " + e.getMessage());
throw new IOException(e + " " + e.getMessage()); }
} catch (InvalidAlgorithmParameterException e) { }
throw new IOException(e + " " + e.getMessage());
} public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort, HttpConnectionParams params) throws IOException {
} try {
return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);
} catch (NoSuchAlgorithmException e) {
public Socket createSocket(String host, int port) throws IOException { throw new IOException(e + " " + e.getMessage());
try { } catch (KeyManagementException e) {
return getSSLContext().getSocketFactory().createSocket(host, port); throw new IOException(e + " " + e.getMessage());
} catch (NoSuchAlgorithmException e) { } catch (KeyStoreException e) {
throw new IOException(e + " " + e.getMessage()); throw new IOException(e + " " + e.getMessage());
} catch (KeyManagementException e) { } catch (InvalidAlgorithmParameterException e) {
throw new IOException(e + " " + e.getMessage()); throw new IOException(e + " " + e.getMessage());
} catch (KeyStoreException e) { }
throw new IOException(e + " " + e.getMessage()); }
} catch (InvalidAlgorithmParameterException e) {
throw new IOException(e + " " + e.getMessage()); public Socket createSocket(String host, int port) throws IOException {
} try {
} return getSSLContext().getSocketFactory().createSocket(host, port);
} catch (NoSuchAlgorithmException e) {
public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException { throw new IOException(e + " " + e.getMessage());
try { } catch (KeyManagementException e) {
return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose); throw new IOException(e + " " + e.getMessage());
} catch (NoSuchAlgorithmException e) { } catch (KeyStoreException e) {
throw new IOException(e + " " + e.getMessage()); throw new IOException(e + " " + e.getMessage());
} catch (KeyManagementException e) { } catch (InvalidAlgorithmParameterException e) {
throw new IOException(e + " " + e.getMessage()); throw new IOException(e + " " + e.getMessage());
} catch (KeyStoreException e) { }
throw new IOException(e + " " + e.getMessage()); }
} catch (InvalidAlgorithmParameterException e) {
throw new IOException(e + " " + e.getMessage()); public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
} try {
} return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose);
} catch (NoSuchAlgorithmException e) {
/** throw new IOException(e + " " + e.getMessage());
* All instances of SSLProtocolSocketFactory are the same. } catch (KeyManagementException e) {
*/ throw new IOException(e + " " + e.getMessage());
@Override } catch (KeyStoreException e) {
public boolean equals(Object obj) { throw new IOException(e + " " + e.getMessage());
return ((obj != null) && obj.getClass().equals(this.getClass())); } catch (InvalidAlgorithmParameterException e) {
} throw new IOException(e + " " + e.getMessage());
}
/** }
* All instances of SSLProtocolSocketFactory have the same hash code.
*/ /**
@Override * All instances of SSLProtocolSocketFactory are the same.
public int hashCode() { */
return this.getClass().hashCode(); @Override
} public boolean equals(Object obj) {
} return ((obj != null) && obj.getClass().equals(this.getClass()));
}
/**
* All instances of SSLProtocolSocketFactory have the same hash code.
*/
@Override
public int hashCode() {
return this.getClass().hashCode();
}
}

View File

@ -0,0 +1,165 @@
/*
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
* Copyright (C) 2011 Mickael Guessant
*
* 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; either version 2
* of the License, or (at your option) any later version.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package davmail.http;
import davmail.ui.SelectCertificateDialog;
import org.apache.log4j.Logger;
import javax.net.ssl.X509KeyManager;
import java.net.Socket;
import java.security.Principal;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Special X509 Key Manager that handles cases where more than one private key
* is sufficient to establish the HTTPs connection by asking the user to
* select one.
*/
public class DavMailX509KeyManager implements X509KeyManager {
protected static final Logger LOGGER = Logger.getLogger(DavMailX509KeyManager.class);
// Wrap an existing key manager to handle most of the interface as a pass through
private final X509KeyManager keyManager;
// Remember selected alias so we don't continually bug the user
private String cachedAlias;
/**
* Build the specialized key manager wrapping the default one
*
* @param keyManager original key manager
*/
public DavMailX509KeyManager(X509KeyManager keyManager) {
this.keyManager = keyManager;
}
/**
* Get the client aliases, simply pass this through to wrapped key manager
*/
public String[] getClientAliases(String string, Principal[] principals) {
return keyManager.getClientAliases(string, principals);
}
/**
* Select a client alias. Some servers are misconfigured and claim to accept
* any client certificate during the SSL handshake, however OWA only authenticates
* using a single certificate.
* <p/>
* This method allows the user to select the right client certificate
*/
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
// Build a list of all aliases
ArrayList<String> aliases = new ArrayList<String>();
for (String keyTypeValue : keyType) {
String[] keyAliases = keyManager.getClientAliases(keyTypeValue, issuers);
if (keyAliases != null) {
aliases.addAll(Arrays.asList(keyAliases));
}
}
// If there are more than one show a dialog and return the selected alias
if (aliases.size() > 1) {
//If there's a saved pattern try to match it
if (cachedAlias != null) {
for (String alias : aliases) {
if (cachedAlias.equals(stripAlias(alias))) {
LOGGER.debug(alias + " matched cached alias: " + cachedAlias);
return alias;
}
}
// pattern didn't match, clear the pattern and ask user to select an alias
cachedAlias = null;
}
String[] aliasesArray = aliases.toArray(new String[aliases.size()]);
SelectCertificateDialog selectCertificateDialog = new SelectCertificateDialog(aliasesArray);
LOGGER.debug("User selected Key Alias: " + selectCertificateDialog.getSelectedAlias());
cachedAlias = stripAlias(selectCertificateDialog.getSelectedAlias().substring(10));
LOGGER.debug("Stored Key Alias Pattern: " + cachedAlias);
return selectCertificateDialog.getSelectedAlias();
// exactly one, simply return that and don't bother the user
} else if (aliases.size() == 1) {
LOGGER.debug("One Private Key found, returning that");
return aliases.get(0);
// none, return null
} else {
LOGGER.debug("No Private Keys found");
return null;
}
}
/**
* PKCS11 aliases are in the format: dd.0, dd is incremented
* every time the SSL connection is re-negotiated
*
* @param alias original alias
* @return alias without prefix
*/
protected String stripAlias(String alias) {
String value = alias;
if (value != null && value.length() > 1) {
char firstChar = value.charAt(0);
int dotIndex = value.indexOf('.');
if (firstChar >= '0' && firstChar <= '9' && dotIndex >= 0) {
value = value.substring(dotIndex+1);
}
}
return value;
}
/**
* Passthrough to wrapped keymanager
*/
public String[] getServerAliases(String string, Principal[] prncpls) {
return keyManager.getServerAliases(string, prncpls);
}
/**
* Passthrough to wrapped keymanager
*/
public String chooseServerAlias(String string, Principal[] prncpls, Socket socket) {
return keyManager.chooseServerAlias(string, prncpls, socket);
}
/**
* Passthrough to wrapped keymanager
*/
public X509Certificate[] getCertificateChain(String string) {
return keyManager.getCertificateChain(string);
}
/**
* Passthrough to wrapped keymanager
*/
public PrivateKey getPrivateKey(String string) {
return keyManager.getPrivateKey(string);
}
}

View File

@ -0,0 +1,111 @@
/*
* DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
* Copyright (C) 2011 Mickael Guessant
*
* 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; either version 2
* of the License, or (at your option) any later version.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package davmail.ui;
import davmail.BundleMessage;
import davmail.ui.tray.DavGatewayTray;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Let user select a client certificate
*/
public class SelectCertificateDialog extends JDialog {
protected JList aliasListBox;
protected String selectedAlias;
/**
* Gets user selected alias.
*
* @return user selected alias
*/
public String getSelectedAlias() {
return this.selectedAlias;
}
/**
* Select a client certificate
*
* @param aliases An array of certificate aliases for the user to pick from
*/
public SelectCertificateDialog(String[] aliases) {
setAlwaysOnTop(true);
setTitle(BundleMessage.format("UI_CERTIFICATE_ALIAS_PROMPT"));
try {
setIconImage(DavGatewayTray.getFrameIcon());
} catch (NoSuchMethodError error) {
DavGatewayTray.debug(new BundleMessage("LOG_UNABLE_TO_SET_ICON_IMAGE"));
}
JPanel questionPanel = new JPanel();
questionPanel.setLayout(new BoxLayout(questionPanel, BoxLayout.Y_AXIS));
JLabel imageLabel = new JLabel();
imageLabel.setIcon(UIManager.getIcon("OptionPane.questionIcon"));
imageLabel.setText(BundleMessage.format("UI_CERTIFICATE_ALIAS_PROMPT"));
questionPanel.add(imageLabel);
aliasListBox = new JList(aliases);
aliasListBox.setMaximumSize(aliasListBox.getPreferredSize());
JPanel aliasPanel = new JPanel();
aliasPanel.setLayout(new BoxLayout(aliasPanel, BoxLayout.Y_AXIS));
aliasPanel.add(aliasListBox);
add(questionPanel, BorderLayout.NORTH);
add(aliasPanel, BorderLayout.CENTER);
add(getButtonPanel(), BorderLayout.SOUTH);
setModal(true);
pack();
// center frame
setLocation(getToolkit().getScreenSize().width / 2 -
getSize().width / 2,
getToolkit().getScreenSize().height / 2 -
getSize().height / 2);
setVisible(true);
requestFocus();
}
protected JPanel getButtonPanel() {
JPanel buttonPanel = new JPanel();
JButton okButton = new JButton(BundleMessage.format("UI_BUTTON_OK"));
JButton cancelButton = new JButton(BundleMessage.format("UI_BUTTON_CANCEL"));
okButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
selectedAlias = aliasListBox.getSelectedValue().toString();
setVisible(false);
}
});
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
selectedAlias = null;
setVisible(false);
}
});
buttonPanel.add(okButton);
buttonPanel.add(cancelButton);
return buttonPanel;
}
}