From 6db2199d0ccfa8ba5a40b08a42164b3623ce74d9 Mon Sep 17 00:00:00 2001 From: mguessan Date: Wed, 17 Jun 2009 16:27:31 +0000 Subject: [PATCH] PKCS11 (smartcard) client certificate support git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@590 3d1905a2-6b24-0410-a738-b14d5a86fcbd --- src/java/davmail/Settings.java | 2 + .../DavGatewaySSLProtocolSocketFactory.java | 102 ++++++++++++++---- src/java/davmail/ui/PasswordPromptDialog.java | 88 +++++++++++++++ src/java/davmail/ui/SettingsFrame.java | 48 +++++++-- src/java/davmailmessages.properties | 7 +- src/java/davmailmessages_fr.properties | 7 +- src/site/xdoc/gettingstarted.xml | 25 +++-- 7 files changed, 235 insertions(+), 44 deletions(-) create mode 100644 src/java/davmail/ui/PasswordPromptDialog.java diff --git a/src/java/davmail/Settings.java b/src/java/davmail/Settings.java index bc25f1ef..5d1e6063 100644 --- a/src/java/davmail/Settings.java +++ b/src/java/davmail/Settings.java @@ -69,6 +69,8 @@ public class Settings { SETTINGS.put("davmail.ssl.keystoreFile", ""); SETTINGS.put("davmail.ssl.keystorePass", ""); SETTINGS.put("davmail.ssl.keyPass", ""); + SETTINGS.put("davmail.ssl.pkcs11Library", ""); + SETTINGS.put("davmail.ssl.pkcs11Config", ""); // logging SETTINGS.put("log4j.rootLogger", Priority.WARN.toString()); diff --git a/src/java/davmail/http/DavGatewaySSLProtocolSocketFactory.java b/src/java/davmail/http/DavGatewaySSLProtocolSocketFactory.java index e4ef07a0..28f04e2b 100644 --- a/src/java/davmail/http/DavGatewaySSLProtocolSocketFactory.java +++ b/src/java/davmail/http/DavGatewaySSLProtocolSocketFactory.java @@ -1,24 +1,29 @@ package davmail.http; -import davmail.Settings; import davmail.BundleMessage; +import davmail.Settings; +import davmail.ui.PasswordPromptDialog; import davmail.ui.tray.DavGatewayTray; import org.apache.commons.httpclient.HttpsURL; import org.apache.commons.httpclient.params.HttpConnectionParams; import org.apache.commons.httpclient.protocol.Protocol; import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; +import sun.security.pkcs11.SunPKCS11; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManager; +import javax.net.ssl.*; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.Socket; import java.net.URL; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; +import java.security.*; +import java.security.cert.CertificateException; /** * Manual Socket Factory. @@ -39,22 +44,49 @@ public class DavGatewaySSLProtocolSocketFactory implements SecureProtocolSocketF port = HttpsURL.DEFAULT_PORT; } Protocol.registerProtocol(url.getProtocol(), - new Protocol(protocol, (ProtocolSocketFactory)new DavGatewaySSLProtocolSocketFactory(), port)); + new Protocol(protocol, (ProtocolSocketFactory) new DavGatewaySSLProtocolSocketFactory(), port)); } } catch (MalformedURLException e) { DavGatewayTray.error(new BundleMessage("LOG_INVALID_URL", urlString)); } } - private SSLContext sslcontext ; + private SSLContext sslcontext; + + private SSLContext createSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException, IOException, CertificateException, InvalidAlgorithmParameterException { + // PKCS11 client certificate settings + String pkcs11Library = Settings.getProperty("davmail.ssl.pkcs11Library"); + if (pkcs11Library != null && pkcs11Library.length() > 0) { + StringBuilder pkcs11Buffer = new StringBuilder(); + pkcs11Buffer.append("name=DavMail\n"); + pkcs11Buffer.append("library=").append(pkcs11Library).append('\n'); + String pkcs11Config = Settings.getProperty("davmail.ssl.pkcs11Config"); + if (pkcs11Config != null && pkcs11Config.length() > 0) { + pkcs11Buffer.append(pkcs11Config).append('\n'); + } + Provider p = new SunPKCS11(new ByteArrayInputStream(pkcs11Buffer.toString().getBytes())); + Security.addProvider(p); + } + + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(/*KeyManagerFactory.getDefaultAlgorithm()*/"NewSunX509"); + KeyStore.Builder scBuilder = KeyStore.Builder.newInstance("PKCS11", null, + new KeyStore.CallbackHandlerProtection(new CallbackHandler() { + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + if (callbacks.length > 0 && callbacks[0] instanceof PasswordCallback) { + PasswordPromptDialog passwordPromptDialog = new PasswordPromptDialog(((PasswordCallback) callbacks[0]).getPrompt()); + ((PasswordCallback) callbacks[0]).setPassword(passwordPromptDialog.getPassword()); + } + } + })); + ManagerFactoryParameters ksParams = new KeyStoreBuilderParameters(scBuilder); + keyManagerFactory.init(ksParams); - private SSLContext createSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException { SSLContext context = SSLContext.getInstance("SSL"); - context.init(null, new TrustManager[]{new DavGatewayX509TrustManager()}, null); + context.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{new DavGatewayX509TrustManager()}, null); return context; } - private SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException { + private SSLContext getSSLContext() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException, IOException, CertificateException, InvalidAlgorithmParameterException { if (this.sslcontext == null) { this.sslcontext = createSSLContext(); } @@ -66,11 +98,17 @@ public class DavGatewaySSLProtocolSocketFactory implements SecureProtocolSocketF try { return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); } catch (NoSuchAlgorithmException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); } catch (KeyManagementException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); } catch (KeyStoreException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + throw new IOException(e + " " + e.getMessage()); + } catch (CertificateException e) { + throw new IOException(e + " " + e.getMessage()); + } catch (InvalidAlgorithmParameterException e) { + throw new IOException(e + " " + e.getMessage()); } } @@ -78,11 +116,17 @@ public class DavGatewaySSLProtocolSocketFactory implements SecureProtocolSocketF try { return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); } catch (NoSuchAlgorithmException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); } catch (KeyManagementException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); } catch (KeyStoreException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + throw new IOException(e + " " + e.getMessage()); + } catch (CertificateException e) { + throw new IOException(e + " " + e.getMessage()); + } catch (InvalidAlgorithmParameterException e) { + throw new IOException(e + " " + e.getMessage()); } } @@ -91,11 +135,17 @@ public class DavGatewaySSLProtocolSocketFactory implements SecureProtocolSocketF try { return getSSLContext().getSocketFactory().createSocket(host, port); } catch (NoSuchAlgorithmException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); } catch (KeyManagementException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); } catch (KeyStoreException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + throw new IOException(e + " " + e.getMessage()); + } catch (CertificateException e) { + throw new IOException(e + " " + e.getMessage()); + } catch (InvalidAlgorithmParameterException e) { + throw new IOException(e + " " + e.getMessage()); } } @@ -103,11 +153,17 @@ public class DavGatewaySSLProtocolSocketFactory implements SecureProtocolSocketF try { return getSSLContext().getSocketFactory().createSocket(socket, host, port, autoClose); } catch (NoSuchAlgorithmException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); } catch (KeyManagementException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); } catch (KeyStoreException e) { - throw new IOException(e+" "+e.getMessage()); + throw new IOException(e + " " + e.getMessage()); + } catch (UnrecoverableKeyException e) { + throw new IOException(e + " " + e.getMessage()); + } catch (CertificateException e) { + throw new IOException(e + " " + e.getMessage()); + } catch (InvalidAlgorithmParameterException e) { + throw new IOException(e + " " + e.getMessage()); } } diff --git a/src/java/davmail/ui/PasswordPromptDialog.java b/src/java/davmail/ui/PasswordPromptDialog.java new file mode 100644 index 00000000..c85fa09a --- /dev/null +++ b/src/java/davmail/ui/PasswordPromptDialog.java @@ -0,0 +1,88 @@ +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; + +/** + * Get smartcard password + */ +public class PasswordPromptDialog extends JDialog { + final JPasswordField passwordField = new JPasswordField(20); + protected char[] password; + + public char[] getPassword() { + return password; + } + + public PasswordPromptDialog(String prompt) { + setAlwaysOnTop(true); + + setTitle(BundleMessage.format("UI_PASSWORD_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(prompt); + questionPanel.add(imageLabel); + + passwordField.setMaximumSize(passwordField.getPreferredSize()); + passwordField.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + password = passwordField.getPassword(); + dispose(); + } + }); + JPanel passwordPanel = new JPanel(); + passwordPanel.setLayout(new BoxLayout(passwordPanel, BoxLayout.Y_AXIS)); + passwordPanel.add(passwordField); + //questionPanel.add(passwordField); + add(questionPanel, BorderLayout.NORTH); + add(passwordPanel, 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) { + password = passwordField.getPassword(); + dispose(); + } + }); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + password = null; + dispose(); + } + }); + + buttonPanel.add(okButton); + buttonPanel.add(cancelButton); + return buttonPanel; + } + +} diff --git a/src/java/davmail/ui/SettingsFrame.java b/src/java/davmail/ui/SettingsFrame.java index 53e0c142..dfa49dd3 100644 --- a/src/java/davmail/ui/SettingsFrame.java +++ b/src/java/davmail/ui/SettingsFrame.java @@ -48,6 +48,9 @@ public class SettingsFrame extends JFrame { JPasswordField keystorePassField; JPasswordField keyPassField; + JTextField pkcs11LibraryField; + JTextArea pkcs11ConfigField; + JComboBox rootLoggingLevelField; JComboBox davmailLoggingLevelField; JComboBox httpclientLoggingLevelField; @@ -211,26 +214,43 @@ public class SettingsFrame extends JFrame { return proxyPanel; } - protected JPanel getEncryptionPanel() { - JPanel encryptionPanel = new JPanel(new GridLayout(4, 2)); - encryptionPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_CERTIFICATE"))); + protected JPanel getKeystorePanel() { + JPanel keyStorePanel = new JPanel(new GridLayout(4, 2)); + keyStorePanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_SERVER_CERTIFICATE"))); keystoreTypeCombo = new JComboBox(new String[]{"JKS", "PKCS12"}); keystoreTypeCombo.setSelectedItem(Settings.getProperty("davmail.ssl.keystoreType")); - keystoreFileField = new JTextField(Settings.getProperty("davmail.ssl.keystoreFile"), 15); + keystoreFileField = new JTextField(Settings.getProperty("davmail.ssl.keystoreFile"), 17); keystorePassField = new JPasswordField(Settings.getProperty("davmail.ssl.keystorePass"), 15); keyPassField = new JPasswordField(Settings.getProperty("davmail.ssl.keyPass"), 15); - addSettingComponent(encryptionPanel, BundleMessage.format("UI_KEY_STORE_TYPE"), keystoreTypeCombo, + addSettingComponent(keyStorePanel, BundleMessage.format("UI_KEY_STORE_TYPE"), keystoreTypeCombo, BundleMessage.format("UI_KEY_STORE_TYPE_HELP")); - addSettingComponent(encryptionPanel, BundleMessage.format("UI_KEY_STORE"), keystoreFileField, + addSettingComponent(keyStorePanel, BundleMessage.format("UI_KEY_STORE"), keystoreFileField, BundleMessage.format("UI_KEY_STORE_HELP")); - addSettingComponent(encryptionPanel, BundleMessage.format("UI_KEY_STORE_PASSWORD"), keystorePassField, + addSettingComponent(keyStorePanel, BundleMessage.format("UI_KEY_STORE_PASSWORD"), keystorePassField, BundleMessage.format("UI_KEY_STORE_PASSWORD_HELP")); - addSettingComponent(encryptionPanel, BundleMessage.format("UI_KEY_PASSWORD"), keyPassField, + addSettingComponent(keyStorePanel, BundleMessage.format("UI_KEY_PASSWORD"), keyPassField, BundleMessage.format("UI_KEY_PASSWORD_HELP")); - return encryptionPanel; + return keyStorePanel; + } + + protected JPanel getSmartcardPanel() { + JPanel smartcardPanel = new JPanel(new GridLayout(2, 2)); + smartcardPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_CLIENT_CERTIFICATE"))); + + pkcs11LibraryField = new JTextField(Settings.getProperty("davmail.ssl.pkcs11Library"), 17); + pkcs11ConfigField = new JTextArea(2, 17); + pkcs11ConfigField.setBorder(pkcs11LibraryField.getBorder()); + pkcs11ConfigField.setFont(pkcs11LibraryField.getFont()); + + addSettingComponent(smartcardPanel, BundleMessage.format("UI_PKCS11_LIBRARY"), pkcs11LibraryField, + BundleMessage.format("UI_PKCS11_LIBRARY_HELP")); + addSettingComponent(smartcardPanel, BundleMessage.format("UI_PKCS11_CONFIG"), pkcs11ConfigField, + BundleMessage.format("UI_PKCS11_CONFIG_HELP")); + + return smartcardPanel; } public JPanel getNetworkSettingsPanel() { @@ -317,6 +337,9 @@ public class SettingsFrame extends JFrame { keystorePassField.setText(Settings.getProperty("davmail.ssl.keystorePass")); keyPassField.setText(Settings.getProperty("davmail.ssl.keyPass")); + pkcs11LibraryField.setText(Settings.getProperty("davmail.ssl.pkcs11Library")); + pkcs11ConfigField.setText(Settings.getProperty("davmail.ssl.pkcs11Config")); + rootLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("rootLogger")); davmailLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("davmail")); httpclientLoggingLevelField.setSelectedItem(Settings.getLoggingLevel("org.apache.commons.httpclient")); @@ -358,9 +381,9 @@ public class SettingsFrame extends JFrame { JPanel encryptionPanel = new JPanel(); encryptionPanel.setLayout(new BoxLayout(encryptionPanel, BoxLayout.Y_AXIS)); - encryptionPanel.add(getEncryptionPanel()); + encryptionPanel.add(getKeystorePanel()); // empty panel - encryptionPanel.add(new JPanel()); + encryptionPanel.add(getSmartcardPanel()); tabbedPane.add(BundleMessage.format("UI_TAB_ENCRYPTION"), encryptionPanel); advancedPanel.add(getNetworkSettingsPanel()); @@ -401,6 +424,9 @@ public class SettingsFrame extends JFrame { Settings.setProperty("davmail.ssl.keystorePass", String.valueOf(keystorePassField.getPassword())); Settings.setProperty("davmail.ssl.keyPass", String.valueOf(keyPassField.getPassword())); + Settings.setProperty("davmail.ssl.pkcs11Library", pkcs11LibraryField.getText()); + Settings.setProperty("davmail.ssl.pkcs11Config", pkcs11ConfigField.getText()); + Settings.setLoggingLevel("rootLogger", (Level) rootLoggingLevelField.getSelectedItem()); Settings.setLoggingLevel("davmail", (Level) davmailLoggingLevelField.getSelectedItem()); Settings.setLoggingLevel("org.apache.commons.httpclient", (Level) httpclientLoggingLevelField.getSelectedItem()); diff --git a/src/java/davmailmessages.properties b/src/java/davmailmessages.properties index d648f518..d8fc9dbb 100644 --- a/src/java/davmailmessages.properties +++ b/src/java/davmailmessages.properties @@ -136,6 +136,7 @@ UI_ABOUT_DAVMAIL_AUTHOR=DavMail Gateway
By Micka UI_ACCEPT_CERTIFICATE=DavMail: Accept certificate ? UI_ALLOW_REMOTE_CONNECTION=Allow Remote Connections: UI_ALLOW_REMOTE_CONNECTION_HELP=Allow remote connections to the gateway (server mode) +UI_PASSWORD_PROMPT=DavMail: Enter password UI_ANSWER_NO=n UI_ANSWER_YES=y UI_BIND_ADDRESS=Bind address: @@ -150,7 +151,6 @@ UI_CALDAV_PORT=Caldav HTTP port: UI_CALDAV_PORT_HELP=Local Caldav server port to configure in Caldav (calendar) client UI_CALENDAR_PAST_EVENTS=Calendar past events: UI_CALENDAR_PAST_EVENTS_HELP=Get events in the past not older than specified days count, leave empty for no limits -UI_CERTIFICATE=Certificate UI_CURRENT_VERSION=Current version: {0}
UI_DAVMAIL_GATEWAY=DavMail Gateway UI_DAVMAIL_SETTINGS=DavMail Gateway Settings @@ -177,6 +177,11 @@ UI_KEY_STORE_PASSWORD=Key store password: UI_KEY_STORE_PASSWORD_HELP=Key store password UI_KEY_STORE_TYPE=Key store type: UI_KEY_STORE_TYPE_HELP=Choose key store type +UI_CLIENT_CERTIFICATE=Client Certificate +UI_PKCS11_LIBRARY=PKCS11 library +UI_PKCS11_LIBRARY_HELP=PKCS11 (smartcard) library path (.so or .dll) +UI_PKCS11_CONFIG=PKCS11 config +UI_PKCS11_CONFIG_HELP=Optional additional PKCS11 settings (slot, nssArgs, ...) UI_LAST_LOG=Last log UI_LAST_MESSAGE=Last message UI_LATEST_VERSION=Latest version available: {0}
A new version of DavMail Gateway is available.
Download latest version
diff --git a/src/java/davmailmessages_fr.properties b/src/java/davmailmessages_fr.properties index 3e9e44ef..59d30f51 100644 --- a/src/java/davmailmessages_fr.properties +++ b/src/java/davmailmessages_fr.properties @@ -150,7 +150,6 @@ UI_CALDAV_PORT=Port HTTP Caldav : UI_CALDAV_PORT_HELP=Port local Caldav à configurer dans le client Caldav (agenda) UI_CALENDAR_PAST_EVENTS=Jours passés du calendrier : UI_CALENDAR_PAST_EVENTS_HELP=Limiter les évènements remontés -UI_CERTIFICATE=Certificat UI_CURRENT_VERSION=Version actuelle : {0}
UI_DAVMAIL_GATEWAY=Passerelle DavMail UI_DAVMAIL_SETTINGS=Configuration Passerelle DavMail @@ -216,3 +215,9 @@ UI_UNTRUSTED_CERTIFICATE=Le certificat fourni par le serveur n''est certifi UI_UNTRUSTED_CERTIFICATE_HTML=Le certificat fourni par le serveur n''est certifié par aucune autorité de confiance,
vous pouvez choisir d''accepter ou de rejeter l''accès
UI_VALID_FROM=Emis le UI_VALID_UNTIL=Expire le +UI_PASSWORD_PROMPT=DavMail : Entrer le mot de passe +UI_PKCS11_LIBRARY_HELP=Chemin de la librarie PKCS11 (carte à puce) (.so or .dll) +UI_PKCS11_LIBRARY=Librairie PKCS11 +UI_PKCS11_CONFIG_HELP=Configuration PKCS11 complémentaire optionnelle (slot, nssArgs, ...) +UI_PKCS11_CONFIG=Configuration PKCS11 +UI_CLIENT_CERTIFICATE=Certificat client \ No newline at end of file diff --git a/src/site/xdoc/gettingstarted.xml b/src/site/xdoc/gettingstarted.xml index 4044de71..70ccf144 100644 --- a/src/site/xdoc/gettingstarted.xml +++ b/src/site/xdoc/gettingstarted.xml @@ -96,11 +96,16 @@ password - Allow remote connections - Allow remote connections to the gateway (server mode) - false + PKCS11 library + PKCS11 (smartcard) library path (.so or .dll) + softokn3.dll - + + PKCS11 config + Optional additional PKCS11 settings (slot, nssArgs, ...) + slot=2 + + Bind Address Bind only to the specified network address 10.0.1.2 @@ -108,7 +113,8 @@ Server certificate hash Manually accepted server certificate hash, contains the SHA1 hash of - a manually accepted certificate (invalid or self signed) + a manually accepted certificate (invalid or self signed) + 9F:CC:59:82:1F:C:CD:29:7C:70:F0:D8:37:B1:77:3F:48:84:AE:C4 @@ -118,15 +124,18 @@ Logging levels - Default, DavMail and HttpClient logging levels, see Log4J documentation for more details + Default, DavMail and HttpClient logging levels, see Log4J documentation for more details + WARN

Uncheck a port to disable matching service.

Activate panel under Proxy tab to set an HTTP proxy and associated credentials if needed

-

Proceeed to Thunderbird mail setup - or OSX iCal setup +

Proceeed to + Thunderbird mail setup + or + OSX iCal setup