source: branches/2.3/security/ExpressoCertLogin/src/LoginApplet.java @ 5898

Revision 5898, 13.5 KB checked in by rafaelraymundo, 12 years ago (diff)

Ticket #2256 - Problemas com o token iKey 2032 / 4000.

Line 
1
2import java.awt.Frame;
3import java.io.IOException;
4import java.net.MalformedURLException;
5import java.net.URL;
6import java.security.GeneralSecurityException;
7import java.security.ProviderException;
8
9import javax.net.ssl.SSLHandshakeException;
10import javax.swing.JApplet;
11import javax.swing.JOptionPane;
12import javax.swing.SwingUtilities;
13import org.apache.commons.httpclient.HttpException;
14
15import netscape.javascript.JSObject;
16
17import br.gov.serpro.cert.DigitalCertificate;
18import br.gov.serpro.setup.Setup;
19import br.gov.serpro.ui.DialogBuilder;
20
21/**
22 * GUI que realiza o login com certificados A1 e A3 ou login com usuário e senha no expresso.
23 * Esta classe estende a classe JApplet
24 * @author Mário César Kolling - mario.kolling@serpro.gov.br
25 */
26public class LoginApplet extends JApplet {
27
28    /**
29     * Valor gerado aleatoriamente
30     */
31    //TODO: Alterar a cor e fonte dos labels e das caixas de texto e senha.
32    private static final long serialVersionUID = -6204158613173951516L;
33    private DigitalCertificate dc;
34    private Setup setup;
35
36    /* (non-Javadoc)
37     * @see java.applet.Applet#init()
38     */
39    public void init() {
40        super.init();
41        this.setSize(0, 0);
42        this.setup = new Setup(this);
43        this.setup.addLanguageResource("ExpressoCertLoginMessages");
44    }
45   
46    private boolean parseVercert(String[] answer, String certificate){
47        boolean tryAgain = false;
48        // Faz o login
49        if (setup.getParameter("debug").equalsIgnoreCase("true") && answer != null) {
50            System.out.println("Código de retorno: " + answer[0].trim());
51        }
52
53        if (answer == null){ // Ação cancelada
54            tryAgain = false;
55            String redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
56                    + ":" + this.getCodeBase().getPort() + "/login.php";
57            try {
58                this.getAppletContext().showDocument(new URL(redirect));
59            } catch (MalformedURLException e) {
60                // TODO Bloco catch gerado automaticamente
61                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
62                    e.printStackTrace();
63                }
64            }
65        }
66        else if (Integer.parseInt(answer[0].trim()) == 0) {
67
68            tryAgain = false;
69            // Pega usuário e senha de credentials[1] e credentials[2], respectivamente
70            // adiciona na página e faz o submit.
71            JSObject document = (JSObject) JSObject.getWindow(this).getMember("document");
72            JSObject loginForm = (JSObject) document.getMember("flogin");
73            JSObject loginField = (JSObject) loginForm.getMember("user");
74            loginField.setMember("value", answer[1].trim());
75
76            JSObject passwdField = (JSObject) loginForm.getMember("passwd");
77            passwdField.setMember("value", answer[2].trim());
78
79            JSObject certificateField = (JSObject) loginForm.getMember("certificado");
80            certificateField.setMember("value", certificate.trim());
81
82            loginForm.call("submit", null);
83            Thread.yield();
84
85        } else if (Integer.parseInt(answer[0].trim()) == 6) {
86
87            tryAgain = false;
88
89            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
90                System.out.println("Mensagem de retorno: " + answer[1].trim());
91            }
92
93            DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), answer[1].trim(), this.setup);
94
95            String redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
96                    + ":" + this.getCodeBase().getPort() + "/login.php?cd=98&ts=202";
97            try {
98                this.getAppletContext().showDocument(new URL(redirect));
99            } catch (MalformedURLException e) {
100                // TODO Bloco catch gerado automaticamente
101                if (this.setup.getParameter("debug").equalsIgnoreCase("true")) {
102                    e.printStackTrace();
103                }
104            }
105        } else {
106            tryAgain = true;
107            dc.destroy();
108            System.gc();
109
110            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
111                System.out.println("Mensagem de retorno: " + answer[1].trim());
112            }
113
114            // Mostra mensagem de erro para o usuário
115            DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), answer[1].trim(), this.setup);
116            Thread.yield();
117        }
118
119        return tryAgain;
120    }
121
122    private boolean parseHandleCertificateResponse(String certificate){
123       
124        // Envia certificado
125       
126        JSObject document = (JSObject) JSObject.getWindow(this).getMember("document");
127        JSObject certificateForm = (JSObject) document.getMember("certificateForm");
128        JSObject certificateField = (JSObject) certificateForm.getMember("certificado");
129        certificateField.setMember("value", certificate);
130
131        // submit e cai fora
132        certificateForm.call("submit", null);
133       
134        dc.destroy();
135        System.gc();
136        Thread.yield();
137
138        return false;
139    }
140
141    /* (non-Javadoc)
142     * @see java.applet.Applet#start()
143     */
144    @Override
145    public void start() {
146        super.start();
147
148        int useCertificate = DigitalCertificate.KEYSTORE_NOT_DETECTED;
149        boolean tryAgain = true;
150
151        do {
152
153            // Cria uma instância de DigitalCertificate e a inicializa
154            // Aqui pega document base e verifica em que aplicação estamos.
155
156            this.dc = new DigitalCertificate(this.getDocumentBase(), setup);
157            useCertificate = dc.init();
158
159            try {
160
161                String redirect = "";
162
163                // Testa em qual aplicação estamos.
164                URL documentURL = this.getDocumentBase();
165
166                if (documentURL.getPath().matches(".*login.php$")){
167                    redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
168                        + ":" + this.getCodeBase().getPort() + "/login.php";
169                }
170                else {
171                    redirect = this.getCodeBase().getProtocol() + "://" + this.getCodeBase().getHost()
172                        + ":" + this.getCodeBase().getPort() + "/preferences/index.php";
173                }
174
175                switch (useCertificate) {
176                    case DigitalCertificate.KEYSTORE_DETECTED:
177                        // Mostra PinNeedeDialog.
178                        char[] pin = null;
179                        if (!DigitalCertificate.isUseMSCapi()){
180                            String sPin = DialogBuilder.showPinDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), this.setup);
181                            if (sPin != null) {
182                                pin = sPin.toCharArray();
183                            }
184                        }
185                        if (DigitalCertificate.isUseMSCapi() || pin != null) {
186                            dc.openKeyStore(pin);
187                            if (documentURL.getPath().matches(".*login.php$")){
188
189                                tryAgain = pin == null ? parseVercert(dc.getCredentials(null, new URL(this.getCodeBase().getProtocol()+"://" +
190                                    this.getCodeBase().getHost() + ":" + this.getCodeBase().getPort() +
191                                    "/security/vercert.php")), dc.getPEMCertificate()) :
192                                    parseVercert(dc.getCredentials(new String(pin), new URL(this.getCodeBase().getProtocol()+"://" +
193                                    this.getCodeBase().getHost() + ":" + this.getCodeBase().getPort() +
194                                    "/security/vercert.php")), dc.getPEMCertificate());
195                            }
196                            else {
197                                tryAgain = parseHandleCertificateResponse(dc.getPEMCertificate());
198                            }
199
200                        } else {
201
202                            // TODO: Notifica usuário
203                            tryAgain = false;
204                            try {
205                                this.getAppletContext().showDocument(new URL(redirect));
206                            } catch (MalformedURLException e) {
207                                // TODO Bloco catch gerado automaticamente
208                                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
209                                    e.printStackTrace();
210                                }
211                            }
212                        }
213
214                        break;
215                    default:
216
217                        // TODO: notifica usuário que token não foi encontrado
218                        // ou repositório de chaves públicas não foi configurado.
219                        // Tentar carregar token/keystore novamente? / Logon sem certificado digital?
220
221                        tryAgain = false;
222                        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
223                            System.out.println("não achou token");
224                        }
225
226                        dc.destroy();
227                        System.gc();
228
229                        try {
230                            this.getAppletContext().showDocument(new URL(redirect));
231                        } catch (MalformedURLException e) {
232                            // TODO Bloco catch gerado automaticamente
233                            if (setup.getParameter("debug").equalsIgnoreCase("true")) {
234                                e.printStackTrace();
235                            }
236                        }
237                }
238
239            } catch (SSLHandshakeException e) {
240                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
241                    e.printStackTrace();
242                }
243                dc.destroy();
244                System.gc();
245                DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
246                        this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet001"), this.setup);
247
248                Thread.yield();
249
250                tryAgain = true;
251            } catch (HttpException e) {
252                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
253                    e.printStackTrace();
254                }
255
256                tryAgain = true;
257                Thread.yield();
258            } catch (GeneralSecurityException e) {
259                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
260                    e.printStackTrace();
261                }
262
263                DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
264                        this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet002"), this.setup);
265
266                Thread.yield();
267                tryAgain = true;
268            } catch (IOException e) {
269                dc.destroy();
270                System.gc();
271
272                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
273                    e.printStackTrace();
274                }
275
276                Throwable cause = null;
277                if ((cause = e.getCause()) != null) {
278                    if (cause instanceof javax.security.auth.login.LoginException) {
279                        DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this), this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet003"), this.setup);
280                    } else {
281                        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
282                            System.out.println("Exception lançada: " + cause.getClass().getCanonicalName());
283                        }
284                    }
285                } else {
286                    if (e instanceof java.net.ConnectException) {
287                        DialogBuilder.showMessageDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
288                                this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet004"), this.setup);
289                    } else {
290                        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
291                            System.out.println("Exception lançada: " + e.getClass().getCanonicalName());
292                        }
293                    }
294                }
295
296                Thread.yield();
297                tryAgain = true;
298            } catch (ProviderException e) {
299
300                dc.destroy();
301                System.gc();
302
303                if (setup.getParameter("debug").equalsIgnoreCase("true")) {
304                    e.printStackTrace();
305                }
306
307                int resultado = DialogBuilder.showConfirmDialog((Frame) SwingUtilities.getAncestorOfClass(Frame.class, this),
308                        //"Deseja tentar carregá-lo novamente?",
309                        this.setup.getLang("ExpressoCertLoginMessages", "LoginApplet005"),
310                        JOptionPane.QUESTION_MESSAGE,
311                        JOptionPane.OK_CANCEL_OPTION, this.setup);
312
313                if (resultado == JOptionPane.OK_OPTION) {
314                    tryAgain = true;
315                } else {
316                    tryAgain = false;
317                }
318
319                Thread.yield();
320            }
321
322        } while (tryAgain);
323
324    }
325
326    /**
327     * Destrói a Applet, executando códigos para desregistrar tokens, keystores, etc.
328     */
329    @Override
330    public void stop() {
331        //super.destroy();
332        if (setup.getParameter("debug").equalsIgnoreCase("true")) {
333            System.out.println("Finalizando Applet de Login!");
334        }
335
336        this.dc.destroy();
337        this.dc = null;
338        System.gc();
339    }
340}
Note: See TracBrowser for help on using the repository browser.