001: /*
002: * Gruntspud
003: *
004: * Copyright (C) 2002 Brett Smith.
005: *
006: * Written by: Brett Smith <t_magicthize@users.sourceforge.net>
007: *
008: * This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public
009: * License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
010: * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
012: *
013: * You should have received a copy of the GNU Library General Public License along with this program; if not, write to the Free
014: * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
015: */
016:
017: package gruntspud.authentication;
018:
019: import gruntspud.Constants;
020: import gruntspud.GruntspudContext;
021: import gruntspud.GruntspudUtil;
022: import gruntspud.ResourceUtil;
023: import gruntspud.StringUtil;
024: import gruntspud.ui.MultilineLabel;
025: import gruntspud.ui.OptionDialog;
026: import gruntspud.ui.UIUtil;
027: import gruntspud.ui.XTextField;
028:
029: import java.awt.BorderLayout;
030: import java.awt.Color;
031: import java.awt.GridBagConstraints;
032: import java.awt.GridBagLayout;
033: import java.awt.Insets;
034: import java.io.BufferedReader;
035: import java.io.File;
036: import java.io.FileInputStream;
037: import java.io.IOException;
038: import java.io.InputStream;
039: import java.io.InputStreamReader;
040: import java.net.Authenticator;
041: import java.net.PasswordAuthentication;
042: import java.util.ResourceBundle;
043:
044: import javax.swing.BorderFactory;
045: import javax.swing.JComboBox;
046: import javax.swing.JComponent;
047: import javax.swing.JLabel;
048: import javax.swing.JOptionPane;
049: import javax.swing.JPanel;
050: import javax.swing.JPasswordField;
051: import javax.swing.SwingUtilities;
052: import javax.swing.UIManager;
053: import javax.swing.border.TitledBorder;
054:
055: /**
056: * Implementation of a <code>java.net.Authenticator</code> that uses the Gruntspud password manager. If the password isn't
057: * currently known, a dialog will be displayed asking the user for it and given the oppurtunity to save the password for later use.
058: *
059: * @author magicthize @created 26 May 2002
060: */
061: public class GruntspudAuthenticator extends Authenticator {
062: static ResourceBundle res = ResourceBundle
063: .getBundle("gruntspud.authentication.ResourceBundle");
064:
065: private final static String[] REMEMBER_PASSWORD = {
066: res
067: .getString("gruntspudAuthenticator.rememberPassword.dontRemember"),
068: res
069: .getString("gruntspudAuthenticator.rememberPassword.rememberForSession"),
070: res
071: .getString("gruntspudAuthenticator.rememberPassword.rememberPermanently") };
072: private GruntspudContext context;
073: private XTextField user;
074: private JPasswordField password;
075: private JPanel passwordPanel;
076: private JComponent parent;
077: private JComboBox rememberPassword;
078: private TitledBorder detailsBorder;
079: private JLabel requestingSchemeLabel;
080: private JLabel requestingProtocolLabel;
081: private JLabel requestingSiteLabel;
082: private JLabel protocolLabel;
083: private JLabel schemeLabel;
084: private JLabel hostLabel;
085: private JLabel userLabel;
086: private boolean forceAskForPassword;
087: private PasswordPairList pairs;
088: private String userName;
089: private Throwable exception;
090: private boolean emphasisePrompt;
091:
092: /**
093: * Creates a new GruntspudAuthenticator.
094: *
095: * @param context context
096: * @throws IOException
097: */
098: public GruntspudAuthenticator(GruntspudContext context) {
099: // Initialise
100: this .context = context;
101:
102: this .context = context;
103:
104: // Create the password panel
105: JPanel s = new JPanel(new GridBagLayout());
106: s.setBorder(detailsBorder = new TitledBorder(""));
107:
108: GridBagConstraints gbc = new GridBagConstraints();
109: gbc.insets = new Insets(3, 3, 3, 3);
110: gbc.anchor = GridBagConstraints.NORTHWEST;
111: gbc.fill = GridBagConstraints.HORIZONTAL;
112:
113: gbc.weightx = 0.0;
114: UIUtil.jGridBagAdd(s, protocolLabel = new JLabel(res
115: .getString("gruntspudAuthenticator.protocol.text")),
116: gbc, GridBagConstraints.RELATIVE);
117: gbc.weightx = 1.0;
118: UIUtil.jGridBagAdd(s, requestingProtocolLabel = new JLabel(),
119: gbc, GridBagConstraints.REMAINDER);
120:
121: gbc.weightx = 0.0;
122: UIUtil.jGridBagAdd(s, schemeLabel = new JLabel(res
123: .getString("gruntspudAuthenticator.scheme.text")), gbc,
124: GridBagConstraints.RELATIVE);
125: gbc.weightx = 1.0;
126: UIUtil.jGridBagAdd(s, requestingSchemeLabel = new JLabel(),
127: gbc, GridBagConstraints.REMAINDER);
128:
129: gbc.weightx = 0.0;
130: UIUtil.jGridBagAdd(s, hostLabel = new JLabel(res
131: .getString("gruntspudAuthenticator.host.text")), gbc,
132: GridBagConstraints.RELATIVE);
133: gbc.weightx = 1.0;
134: UIUtil.jGridBagAdd(s, requestingSiteLabel = new JLabel(), gbc,
135: GridBagConstraints.REMAINDER);
136:
137: gbc.weightx = 0.0;
138: UIUtil.jGridBagAdd(s, userLabel = new JLabel(res
139: .getString("gruntspudAuthenticator.user.text")), gbc,
140: GridBagConstraints.RELATIVE);
141: gbc.weightx = 1.0;
142: UIUtil.jGridBagAdd(s, user = new XTextField(10), gbc,
143: GridBagConstraints.REMAINDER);
144:
145: gbc.weightx = 0.0;
146: UIUtil.jGridBagAdd(s, new JLabel(res
147: .getString("gruntspudAuthenticator.password.text")),
148: gbc, GridBagConstraints.RELATIVE);
149: gbc.weightx = 1.0;
150: UIUtil.jGridBagAdd(s, password = new JPasswordField(10), gbc,
151: GridBagConstraints.REMAINDER);
152: gbc.weightx = 0.0;
153:
154: gbc.weightx = 2.0;
155: UIUtil.jGridBagAdd(s, rememberPassword = new JComboBox(
156: REMEMBER_PASSWORD), gbc, GridBagConstraints.REMAINDER);
157:
158: //
159: // Icon panel
160: JLabel i = new JLabel(UIUtil
161: .getCachedIcon(Constants.ICON_TOOL_LARGE_LOCK));
162: i.setVerticalAlignment(JLabel.NORTH);
163: i.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 4));
164:
165: //
166: passwordPanel = new JPanel(new BorderLayout());
167: passwordPanel.add(i, BorderLayout.WEST);
168: passwordPanel.add(s, BorderLayout.CENTER);
169: }
170:
171: /**
172: * Return a list of all the password pairs
173: *
174: * @return password pair list
175: */
176: public PasswordPairList getPasswordPairList() {
177: return pairs;
178: }
179:
180: /**
181: * Initiailise the autenticator. Should be called just after instantiation
182: *
183: * @param context context
184: * @throws IOException if password list cannot be loaded
185: */
186: public void init(GruntspudContext context) throws IOException {
187: //
188: File passwordFile = GruntspudUtil.getPreferenceFile(
189: "gruntspud.passwords", false);
190: pairs = new PasswordPairList(passwordFile, context);
191:
192: //
193: // If the password file exists, check the first line to see if it is
194: // in the old format. If it is, offer to encrypt the file
195: if (passwordFile.exists()) {
196: InputStream in = null;
197:
198: try {
199: // Check the first line to see if it is encrypted or not
200: in = new FileInputStream(passwordFile);
201:
202: BufferedReader r = new BufferedReader(
203: new InputStreamReader(in));
204: String format = r.readLine();
205: in.close();
206: in = null;
207:
208: // Now load the password file again
209: pairs.loadPasswordFile();
210:
211: if (((format == null) || !format.startsWith("#"
212: + PasswordPairList.FORMAT_KEY))
213: && context.getEncrypter() != null) {
214: askEncrypt();
215: }
216: } finally {
217: if (in != null) {
218: in.close();
219: }
220: }
221: } else if (context.getEncrypter() != null) {
222: askEncrypt();
223: }
224: }
225:
226: /**
227: * Show a dialog asking the use for a new master password. The user must enter the same password twice, then an 2 element array
228: * of the old password and new password as a char[] array is returned. If the user cancels <code>null</code> will be
229: * returned.
230: *
231: * @param context context
232: * @param parent parent component
233: * @param text help text
234: * @param title dialog title
235: * @param checkAgainstOld make sure the old password matches first
236: *
237: * @return 2 element array of char[], first element is old password, second is new
238: */
239: public char[][] showMasterPasswordConfirmationDialog(
240: GruntspudContext context, JComponent parent, String text,
241: String title, final boolean checkAgainstOld) {
242: //
243: JPanel t = new JPanel(new BorderLayout());
244:
245: if (text != null) {
246: t.add(new MultilineLabel(text), BorderLayout.NORTH);
247:
248: }
249: t
250: .setBorder(BorderFactory
251: .createTitledBorder(res
252: .getString("gruntspudAuthenticator.masterPasswordConfirmation.borderTitle")));
253:
254: //
255: JPanel p = new JPanel(new GridBagLayout());
256: p.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
257:
258: GridBagConstraints gbc = new GridBagConstraints();
259: gbc.anchor = GridBagConstraints.WEST;
260: gbc.fill = GridBagConstraints.BOTH;
261: gbc.insets = new Insets(2, 2, 2, 2);
262: gbc.weightx = 0.0;
263:
264: final JPasswordField oldPassword = checkAgainstOld ? new JPasswordField(
265: 15)
266: : null;
267:
268: if (checkAgainstOld) {
269: UIUtil
270: .jGridBagAdd(
271: p,
272: new JLabel(
273: res
274: .getString("gruntspudAuthenticator.masterPasswordConfirmation.oldPassword.text")),
275: gbc, GridBagConstraints.RELATIVE);
276: gbc.weightx = 1.0;
277: UIUtil.jGridBagAdd(p, oldPassword, gbc,
278: GridBagConstraints.REMAINDER);
279: gbc.weightx = 0.0;
280: }
281:
282: UIUtil
283: .jGridBagAdd(
284: p,
285: new JLabel(
286: res
287: .getString("gruntspudAuthenticator.masterPasswordConfirmation.newPassword.text")),
288: gbc, GridBagConstraints.RELATIVE);
289: gbc.weightx = 1.0;
290:
291: final JPasswordField newPassword = new JPasswordField(15);
292: UIUtil.jGridBagAdd(p, newPassword, gbc,
293: GridBagConstraints.REMAINDER);
294: gbc.weightx = 0.0;
295: UIUtil
296: .jGridBagAdd(
297: p,
298: new JLabel(
299: res
300: .getString("gruntspudAuthenticator.masterPasswordConfirmation.confirmPassword.text")),
301: gbc, GridBagConstraints.RELATIVE);
302: gbc.weightx = 1.0;
303:
304: final JPasswordField confirmPassword = new JPasswordField(15);
305: UIUtil.jGridBagAdd(p, confirmPassword, gbc,
306: GridBagConstraints.REMAINDER);
307: gbc.weightx = 0.0;
308: t.add(p, BorderLayout.CENTER);
309:
310: //
311: final OptionDialog.Option ok = new OptionDialog.Option(
312: res
313: .getString("gruntspudAuthenticator.masterPasswordConfirmation.optionDialog.option.ok.text"),
314: res
315: .getString("gruntspudAuthenticator.masterPasswordConfirmation.optionDialog.option.ok.toolTipText"),
316: ResourceUtil
317: .getResourceMnemonic(
318: res,
319: "gruntspudAuthenticator.masterPasswordConfirmation.optionDialog.option.ok.mnemonic"));
320: final OptionDialog.Option cancel = new OptionDialog.Option(
321: res
322: .getString("gruntspudAuthenticator.masterPasswordConfirmation.optionDialog.option.cancel.text"),
323: res
324: .getString("gruntspudAuthenticator.masterPasswordConfirmation.optionDialog.option.cancel.toolTipText"),
325: ResourceUtil
326: .getResourceMnemonic(
327: res,
328: "gruntspudAuthenticator.masterPasswordConfirmation.optionDialog.option.cancel.mnemonic"));
329: OptionDialog.Option opt = OptionDialog.showOptionDialog(
330: "passwordConfirm", context, parent,
331: new OptionDialog.Option[] { ok, cancel }, t, title, ok,
332: new OptionDialog.Callback() {
333: public boolean canClose(OptionDialog dialog,
334: OptionDialog.Option option) {
335: if (option == cancel) {
336: return true;
337: }
338:
339: char[] p1 = newPassword.getPassword();
340: char[] p2 = confirmPassword.getPassword();
341:
342: if (checkAgainstOld) {
343: char[] p3 = oldPassword.getPassword();
344:
345: try {
346: if (!getPasswordPairList()
347: .checkMasterPassword(p3)) {
348: JOptionPane
349: .showMessageDialog(
350: dialog,
351: res
352: .getString("gruntspudAuthenticator.masterPasswordConfirmation.error.oldPasswordIncorrect.text"),
353: res
354: .getString("gruntspudAuthenticator.masterPasswordConfirmation.error.oldPasswordIncorrect.title"),
355: JOptionPane.ERROR_MESSAGE);
356:
357: return false;
358: }
359: } catch (IOException ioe) {
360: JOptionPane
361: .showMessageDialog(
362: dialog,
363: ioe.getMessage(),
364: res
365: .getString("gruntspudAuthenticator.masterPasswordConfirmation.error.ioException.title"),
366: JOptionPane.ERROR_MESSAGE);
367:
368: return false;
369: }
370: }
371:
372: if (!(new String(p1).equals(new String(p2)))) {
373: JOptionPane
374: .showMessageDialog(
375: dialog,
376: res
377: .getString("gruntspudAuthenticator.masterPasswordConfirmation.error.mismatched.text"),
378: res
379: .getString("gruntspudAuthenticator.masterPasswordConfirmation.error.mismatched.title"),
380: JOptionPane.ERROR_MESSAGE);
381:
382: return false;
383: }
384:
385: return true;
386: }
387: }
388:
389: , false, true, null, UIUtil
390: .getCachedIcon(Constants.ICON_TOOL_LARGE_LOCK));
391:
392: if (opt != ok) {
393: return null;
394: }
395:
396: return new char[][] {
397: checkAgainstOld ? oldPassword.getPassword() : null,
398: newPassword.getPassword() };
399: }
400:
401: private void askEncrypt() throws IOException {
402: final OptionDialog.Option yes = new OptionDialog.Option(
403: res
404: .getString("gruntspudAuthenticator.askEncrypt.optionDialog.option.ok.text"),
405: res
406: .getString("gruntspudAuthenticator.askEncrypt.optionDialog.option.ok.toolTipText"),
407: ResourceUtil
408: .getResourceMnemonic(res,
409: "gruntspudAuthenticator.askEncrypt.optionDialog.option.ok.mnemonic"));
410: final OptionDialog.Option no = new OptionDialog.Option(
411: res
412: .getString("gruntspudAuthenticator.askEncrypt.optionDialog.option.cancel.text"),
413: res
414: .getString("gruntspudAuthenticator.askEncrypt.optionDialog.option.cancel.toolTipText"),
415: ResourceUtil
416: .getResourceMnemonic(res,
417: "gruntspudAuthenticator.askEncrypt.optionDialog.option.cancel.mnemonic"));
418:
419: OptionDialog.Option opt = OptionDialog
420: .showOptionDialog(
421: "encryptPasswordFile",
422: context,
423: context.getHost().getMainComponent(),
424: new OptionDialog.Option[] { yes, no },
425: res
426: .getString("gruntspudAuthenticator.askEncrypt.optionDialog.text"),
427: res
428: .getString("gruntspudAuthenticator.askEncrypt.optionDialog.title"),
429: yes, null, false, true);
430:
431: //`Encrypt the passwords if required
432: if (opt == yes) {
433: OptionDialog.Option next = new OptionDialog.Option("Next",
434: "Provide the master password to use.", 'n');
435: OptionDialog
436: .showOptionDialog(
437: "nextQuestionIsPassword",
438: context,
439: context.getHost().getMainComponent(),
440: new OptionDialog.Option[] { next },
441: res
442: .getString("gruntspudAuthenticator.encrypt.optionDialog.text"),
443: res
444: .getString("gruntspudAuthenticator.encrypt.optionDialog.title"),
445: yes, null, false, true);
446:
447: String extraMessage = null;
448:
449: while (true) {
450: char[] pw = getMasterPassword(extraMessage, context
451: .getHost().getMainComponent());
452:
453: if (pw == null) {
454: JOptionPane
455: .showMessageDialog(
456: context.getHost()
457: .getMainComponent(),
458: res
459: .getString("gruntspudAuthenticator.encrypt.getMasswordPassword.aborted.text"),
460: res
461: .getString("gruntspudAuthenticator.encrypt.getMasswordPassword.aborted.title"),
462: JOptionPane.INFORMATION_MESSAGE);
463: opt = no;
464:
465: break;
466: } else {
467: if (pw.length < 6) {
468: extraMessage = res
469: .getString("gruntspudAuthenticator.encrypt.getMasswordPassword.extraMessage.text");
470: } else {
471: pairs.setMasterPassword(pw);
472: pairs.encryptAllPairs();
473:
474: break;
475: }
476: }
477: }
478: }
479:
480: //
481: pairs.setEncrypted(opt == yes);
482: pairs.savePasswordFile();
483: }
484:
485: /**
486: * Show a dialog asking for the master password
487: *
488: * @param message message to show
489: * @param parent parent component
490: *
491: * @return master password (or <code>null</code> if aborted)
492: */
493: public char[] getMasterPassword(String message, JComponent parent) {
494: //
495: JPanel t = new JPanel(new BorderLayout());
496: t
497: .add(
498: new MultilineLabel(
499: res
500: .getString("gruntspudAuthenticator.getMasterPassword.text")),
501: BorderLayout.CENTER);
502:
503: if (message != null) {
504: JLabel mesg = new JLabel(message, JLabel.CENTER);
505: mesg.setForeground(Color.red);
506: t.add(mesg, BorderLayout.SOUTH);
507: }
508:
509: t
510: .setBorder(BorderFactory
511: .createTitledBorder(res
512: .getString("gruntspudAuthenticator.getMasterPassword.borderTitle")));
513:
514: //
515: JPanel p = new JPanel(new GridBagLayout());
516: p.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
517:
518: GridBagConstraints gbc = new GridBagConstraints();
519: gbc.anchor = GridBagConstraints.WEST;
520: gbc.fill = GridBagConstraints.HORIZONTAL;
521: gbc.insets = new Insets(2, 2, 2, 2);
522: gbc.weightx = 0.0;
523: UIUtil
524: .jGridBagAdd(
525: p,
526: new JLabel(
527: res
528: .getString("gruntspudAuthenticator.getMasterPassword.password")),
529: gbc, GridBagConstraints.RELATIVE);
530: gbc.weightx = 1.0;
531:
532: JPasswordField password = new JPasswordField(15);
533: password.grabFocus();
534: UIUtil.jGridBagAdd(p, password, gbc,
535: GridBagConstraints.REMAINDER);
536: t.add(p, BorderLayout.CENTER);
537:
538: //
539: final OptionDialog.Option ok = new OptionDialog.Option(
540: res
541: .getString("gruntspudAuthenticator.getMasterPassword.optionDialog.option.ok.text"),
542: res
543: .getString("gruntspudAuthenticator.getMasterPassword.optionDialog.option.ok.toolTipText"),
544: ResourceUtil
545: .getResourceMnemonic(res,
546: "gruntspudAuthenticator.getMasterPassword.optionDialog.option.ok.mnemonic"));
547: final OptionDialog.Option cancel = new OptionDialog.Option(
548: res
549: .getString("gruntspudAuthenticator.getMasterPassword.optionDialog.option.cancel.text"),
550: res
551: .getString("gruntspudAuthenticator.getMasterPassword.optionDialog.option.cancel.toolTipText"),
552: ResourceUtil
553: .getResourceMnemonic(res,
554: "gruntspudAuthenticator.getMasterPassword.optionDialog.option.cancel.mnemonic"));
555:
556: OptionDialog.Option opt = OptionDialog
557: .showOptionDialog(
558: "masterPassword",
559: context,
560: parent,
561: new OptionDialog.Option[] { ok, cancel },
562: t,
563: res
564: .getString("gruntspudAuthenticator.getMasterPassword.optionDialog.title"),
565: ok,
566: null,
567: false,
568: true,
569: null,
570: UIUtil
571: .getCachedIcon(Constants.ICON_TOOL_LARGE_LOCK));
572:
573: if (opt != ok) {
574: return null;
575: }
576:
577: return password.getPassword();
578: }
579:
580: /**
581: * Set whether the master password should be asked for if it is needed. This should be set just before any operation that might
582: * require the use of a password is run.
583: *
584: * @param forceAskForPassword always ask for the master password next time it is needed
585: */
586: public void setForceAskForPassword(boolean forceAskForPassword) {
587: this .forceAskForPassword = forceAskForPassword;
588: }
589:
590: /**
591: * Set if the next request for a password should emphasise the 'prompt' field by colouring it red. This would normally be used
592: * if this is the second request for a password as the first one was incorrect in some way.
593: *
594: * @param emphasisePrompt emphasis prompt
595: */
596: public void setEmphasisePrompt(boolean emphasisePrompt) {
597: this .emphasisePrompt = emphasisePrompt;
598: }
599:
600: /**
601: * Set the parent component to use as a parent for the modal authentication dialog (should it be displayed).
602: *
603: * @param parent parent component
604: */
605: public void setParentComponent(JComponent parent) {
606: this .parent = parent;
607: }
608:
609: /**
610: * Set the user name to use next time a password is requested
611: *
612: * @param userName user name
613: */
614: public void setUserName(String userName) {
615: this .userName = userName;
616: }
617:
618: public void updateUI() {
619: SwingUtilities.updateComponentTreeUI(passwordPanel);
620: }
621:
622: protected PasswordAuthentication getPasswordAuthentication() {
623: exception = null;
624: try {
625: Constants.SYSTEM_LOG
626: .info("Some network access requested authentication");
627:
628: String host = (getRequestingSite() == null) ? res
629: .getString("gruntspudAuthenticator.auth.unknownSite")
630: : getRequestingSite().getHostName();
631: String scheme = getRequestingScheme();
632: String prompt = getRequestingPrompt();
633:
634: requestingSchemeLabel.setText(scheme);
635: requestingSchemeLabel.setToolTipText(scheme);
636: requestingProtocolLabel.setText(getRequestingProtocol());
637: requestingSiteLabel.setText(host);
638: detailsBorder.setTitle(prompt);
639: detailsBorder.setTitleColor(emphasisePrompt ? Color.red
640: : UIManager.getColor("TitledBorder.titleColor"));
641:
642: PasswordKey key = new PasswordKey(getRequestingProtocol(),
643: getRequestingScheme(), host);
644:
645: // First check the session passwords, then the persistant ones for a
646: // match on the protocol / scheme / host name
647: String userPassword = null;
648: PasswordPair pair = pairs.getPair(key);
649:
650: if (pair == null) {
651: rememberPassword.setSelectedIndex(1);
652: } else {
653: userPassword = pair.getUserPassword();
654:
655: if (pair.isPersistant()) {
656: rememberPassword.setSelectedIndex(2);
657: } else {
658: rememberPassword.setSelectedIndex(0);
659: }
660: }
661:
662: // Decrypt the password if necessary
663: if ((userPassword != null) && pairs.isEncrypted()) {
664: String message = null;
665:
666: while (true) {
667: if (pairs.getMasterPassword() == null) {
668: pairs.setMasterPassword(getMasterPassword(
669: message, parent));
670:
671: }
672: if (pairs.getMasterPassword() == null) {
673: return null;
674: }
675:
676: if (pairs.checkMasterPassword(pairs
677: .getMasterPassword())) {
678: break;
679: } else {
680: message = res
681: .getString("gruntspudAuthenticator.auth.incorrectPassword.text");
682: pairs.setMasterPassword(null);
683: }
684: }
685:
686: if (context.getEncrypter() == null) {
687: throw new IOException(
688: res
689: .getString("gruntspudAuthenticator.auth.error.encrypterNotAvailable.text"));
690: }
691:
692: userPassword = context.getEncrypter().decryptString(
693: userPassword, pairs.getMasterPassword());
694: }
695:
696: // Get the user and password
697: char[] passwordChars = null;
698:
699: if ((userPassword != null) && (userPassword.length() != 0)) {
700: String[] s = StringUtil.splitString(userPassword, '@');
701:
702: if (userName == null) {
703: userName = s[0];
704:
705: }
706: if (s.length > 1) {
707: passwordChars = s[1].toCharArray();
708: }
709: }
710:
711: boolean askForPassword = forceAskForPassword
712: || (passwordChars == null) || (userName == null);
713:
714: // Only ask for the password if we do not already know it
715: if (askForPassword) {
716: user.setEnabled(userName == null);
717: user.setText((userName == null) ? "" : userName);
718: password.setText((passwordChars == null) ? ""
719: : new String(passwordChars));
720:
721: // Set the focus
722: if (userName == null) {
723: password.grabFocus();
724: } else {
725: user.grabFocus();
726:
727: // I really don't know why this is necessary ...... If this is not
728: // done the password caret sits at about position 8 and throws exceptions
729: // and stuff .. ?
730: }
731: password.setCaretPosition(0);
732:
733: // Show the dialog
734: final OptionDialog.Option ok = new OptionDialog.Option(
735: res
736: .getString("gruntspudAuthenticator.auth.optionDialog.option.ok.text"),
737: res
738: .getString("gruntspudAuthenticator.auth.optionDialog.option.ok.toolTipText"),
739: ResourceUtil
740: .getResourceMnemonic(res,
741: "gruntspudAuthenticator.auth.optionDialog.option.ok.mnemonic"));
742: final OptionDialog.Option cancel = new OptionDialog.Option(
743: res
744: .getString("gruntspudAuthenticator.auth.optionDialog.option.cancel.text"),
745: res
746: .getString("gruntspudAuthenticator.auth.optionDialog.option.cancel.toolTipText"),
747: ResourceUtil
748: .getResourceMnemonic(res,
749: "gruntspudAuthenticator.auth.optionDialog.option.cancel.mnemonic"));
750:
751: OptionDialog.Option opt = OptionDialog
752: .showOptionDialog(
753: "password",
754: context,
755: parent,
756: new OptionDialog.Option[] { ok, cancel },
757: passwordPanel,
758: res
759: .getString("gruntspudAuthenticator.auth.optionDialog.title"),
760: ok, null, false, true);
761:
762: if (opt != ok) {
763: return null;
764: }
765:
766: userName = user.getText();
767: passwordChars = password.getPassword();
768:
769: // If we are to rememeber the password ..
770: if (rememberPassword.getSelectedIndex() != 0) {
771: if (pairs.isEncrypted()
772: && (pairs.getMasterPassword() == null)) {
773: String message = null;
774:
775: while (true) {
776: if (pairs.getMasterPassword() == null) {
777: pairs
778: .setMasterPassword(getMasterPassword(
779: message, parent));
780:
781: }
782: if (pairs.getMasterPassword() == null) {
783: throw new IOException(
784: res
785: .getString("gruntspudAuthenticator.auth.error.masterPasswordNotSupplie.text"));
786: }
787:
788: if (pairs.checkMasterPassword(pairs
789: .getMasterPassword())) {
790: break;
791: } else {
792: message = res
793: .getString("gruntspudAuthenticator.auth.incorrectPassword.text");
794: pairs.setMasterPassword(null);
795: }
796: }
797: }
798:
799: String upw = userName + "@"
800: + new String(passwordChars);
801: String epw = context.getEncrypter() != null
802: && pairs.isEncrypted() ? context
803: .getEncrypter().encryptString(upw,
804: pairs.getMasterPassword()) : upw;
805: PasswordPair p = new PasswordPair(key, epw);
806: pairs.addPair(p);
807:
808: if (rememberPassword.getSelectedIndex() == 2) {
809: p.setPersistant(true);
810: pairs.savePasswordFile();
811: }
812: }
813: }
814:
815: //
816: return new PasswordAuthentication(userName, passwordChars);
817: } catch (Throwable t) {
818: exception = t;
819: Constants.SYSTEM_LOG.error(
820: "Password authentication failed.", t);
821: return null;
822: } finally {
823: userName = null;
824: forceAskForPassword = false;
825: }
826: }
827:
828: /**
829: * Return the last exception
830: *
831: * @return last exceptoion
832: */
833: public Throwable getException() {
834: return exception;
835: }
836: }
|