View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2009  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  package davmail.ui;
20  
21  import davmail.BundleMessage;
22  import davmail.http.DavGatewayX509TrustManager;
23  import davmail.ui.tray.DavGatewayTray;
24  
25  import javax.swing.*;
26  import java.awt.*;
27  import java.lang.reflect.InvocationTargetException;
28  import java.security.cert.X509Certificate;
29  import java.text.DateFormat;
30  import java.util.Date;
31  
32  /**
33   * Accept certificate dialog
34   */
35  public class AcceptCertificateDialog extends JDialog {
36      protected boolean accepted;
37  
38      /**
39       * Accept status.
40       *
41       * @return true if user accepted certificate
42       */
43      public boolean isAccepted() {
44          return accepted;
45      }
46  
47      /**
48       * Add a new JLabel to panel with <b>label</b>: value text.
49       *
50       * @param panel certificate details panel
51       * @param label certificate attribute label
52       * @param value certificate attribute value
53       */
54      protected void addFieldValue(JPanel panel, String label, String value) {
55          JPanel fieldPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
56          fieldPanel.add(new JLabel("<html><b>" + label + ":</b></html>"));
57          fieldPanel.add(new JLabel(value));
58          panel.add(fieldPanel);
59      }
60  
61      /**
62       * Accept certificate dialog.
63       *
64       * @param certificate certificate sent by server
65       */
66      public AcceptCertificateDialog(X509Certificate certificate) {
67          setAlwaysOnTop(true);
68          String sha1Hash = DavGatewayX509TrustManager.getFormattedHash(certificate);
69          DateFormat formatter = DateFormat.getDateInstance(DateFormat.MEDIUM);
70  
71          setTitle(BundleMessage.format("UI_ACCEPT_CERTIFICATE"));
72          try {
73              setIconImages(DavGatewayTray.getFrameIcons());
74          } catch (NoSuchMethodError error) {
75              DavGatewayTray.debug(new BundleMessage("LOG_UNABLE_TO_SET_ICON_IMAGE"));
76          }
77  
78          JPanel subjectPanel = new JPanel();
79          subjectPanel.setLayout(new BoxLayout(subjectPanel, BoxLayout.Y_AXIS));
80          subjectPanel.setBorder(BorderFactory.createTitledBorder(BundleMessage.format("UI_SERVER_CERTIFICATE")));
81          addFieldValue(subjectPanel, BundleMessage.format("UI_ISSUED_TO"), DavGatewayX509TrustManager.getRDN(certificate.getSubjectX500Principal()));
82          addFieldValue(subjectPanel, BundleMessage.format("UI_ISSUED_BY"), DavGatewayX509TrustManager.getRDN(certificate.getIssuerX500Principal()));
83          Date now = new Date();
84          String notBefore = formatter.format(certificate.getNotBefore());
85          if (now.before(certificate.getNotBefore())) {
86              notBefore = "<html><font color=\"#FF0000\">" + notBefore + "</font></html>";
87          }
88          addFieldValue(subjectPanel, BundleMessage.format("UI_VALID_FROM"), notBefore);
89          String notAfter = formatter.format(certificate.getNotAfter());
90          if (now.after(certificate.getNotAfter())) {
91              notAfter = "<html><font color=\"#FF0000\">" + notAfter + "</font></html>";
92          }
93          addFieldValue(subjectPanel, BundleMessage.format("UI_VALID_UNTIL"), notAfter);
94          addFieldValue(subjectPanel, BundleMessage.format("UI_SERIAL"), DavGatewayX509TrustManager.getFormattedSerial(certificate));
95          addFieldValue(subjectPanel, BundleMessage.format("UI_FINGERPRINT"), sha1Hash);
96  
97          JPanel warningPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
98          JLabel imageLabel = new JLabel();
99          imageLabel.setIcon(UIManager.getIcon("OptionPane.warningIcon"));
100         imageLabel.setText(BundleMessage.format("UI_UNTRUSTED_CERTIFICATE_HTML"));
101         warningPanel.add(imageLabel);
102         add(warningPanel, BorderLayout.NORTH);
103         add(subjectPanel, BorderLayout.CENTER);
104         add(getButtonPanel(), BorderLayout.SOUTH);
105         setModal(true);
106 
107         pack();
108         // center frame
109         setLocation(getToolkit().getScreenSize().width / 2 -
110                 getSize().width / 2,
111                 getToolkit().getScreenSize().height / 2 -
112                         getSize().height / 2);
113 	setAlwaysOnTop(true);
114         setVisible(true);
115     }
116 
117     protected JPanel getButtonPanel() {
118         JPanel buttonPanel = new JPanel();
119         JButton accept = new JButton(BundleMessage.format("UI_BUTTON_ACCEPT"));
120         JButton deny = new JButton(BundleMessage.format("UI_BUTTON_DENY"));
121         accept.addActionListener(evt -> {
122             accepted = true;
123             setVisible(false);
124         });
125         deny.addActionListener(evt -> {
126             accepted = false;
127             setVisible(false);
128         });
129 
130         buttonPanel.add(accept);
131         buttonPanel.add(deny);
132         return buttonPanel;
133     }
134 
135 
136     /**
137      * Display certificate accept dialog and get user answer.
138      *
139      * @param certificate certificate sent by server
140      * @return true if user accepted certificate
141      */
142     public static boolean isCertificateTrusted(final X509Certificate certificate) {
143         final boolean[] answer = new boolean[1];
144         try {
145             SwingUtilities.invokeAndWait(() -> {
146                 AcceptCertificateDialog certificateDialog = new AcceptCertificateDialog(certificate);
147                 answer[0] = certificateDialog.isAccepted();
148             });
149         } catch (InterruptedException ie) {
150             DavGatewayTray.error(new BundleMessage("UI_ERROR_WAITING_FOR_CERTIFICATE_CHECK"), ie);
151             Thread.currentThread().interrupt();
152         } catch (InvocationTargetException ite) {
153             DavGatewayTray.error(new BundleMessage("UI_ERROR_WAITING_FOR_CERTIFICATE_CHECK"), ite);
154         }
155 
156         return answer[0];
157     }
158 }