/******************************************************************************* * Copyright (c) 2013 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.foundation.security; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import javax.crypto.spec.PBEKeySpec; import org.eclipse.core.runtime.Path; import org.eclipse.equinox.security.storage.EncodingUtils; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ModifyEvent; import org.eclipse.swt.events.ModifyListener; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.forms.FormDialog; import org.eclipse.ui.forms.IManagedForm; import org.eclipse.ui.forms.widgets.ExpandableComposite; import org.eclipse.ui.forms.widgets.FormText; import org.eclipse.ui.forms.widgets.FormToolkit; import org.eclipse.ui.forms.widgets.ScrolledForm; import org.eclipse.ui.forms.widgets.Section; import org.eclipse.ui.forms.widgets.TableWrapData; import org.eclipse.ui.forms.widgets.TableWrapLayout; /** * */ public class DescriptiveStorageLoginDialog extends FormDialog { private static final String HELP_ID = "org.jboss.tools.foundation.security.linux.sec_storage_context"; //$NON-NLS-1$ private static final String DIGEST_ALGORITHM = "MD5"; //$NON-NLS-1$ protected Text password; protected Text confirm; private Label statusLabel; protected Button showPassword; protected Button okButton; protected PBEKeySpec generatedPassword; protected final boolean confirmPassword; protected final boolean passwordChange; protected final String location; /** * Create new dialog instance * * @param confirmPassword * @param passwordChange * @param location */ public DescriptiveStorageLoginDialog(boolean confirmPassword, boolean passwordChange, String location) { super(getWorkbenchShell()); this.confirmPassword = confirmPassword; this.passwordChange = passwordChange; this.location = location; } /** * Get the shell from an active window. If not found, returns null. */ private static Shell getWorkbenchShell() { if (PlatformUI.isWorkbenchRunning()) { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) return window.getShell(); } return null; } /** * Get the generated password * * @return {@link PBEKeySpec} instance of password */ public PBEKeySpec getGeneratedPassword() { return generatedPassword; } @Override protected void createButtonsForButtonBar(Composite parent) { okButton = createButton(parent, IDialogConstants.OK_ID, Messages.ButtonLogin, true); okButton.setEnabled(false); createButton(parent, IDialogConstants.CANCEL_ID, Messages.ButtonExit, false); } @Override protected boolean isResizable() { return false; } @Override protected void configureShell(Shell shell) { super.configureShell(shell); shell.setText(Messages.DialogTitle); PlatformUI.getWorkbench().getHelpSystem().setHelp(shell, HELP_ID); shell.setSize(700, 500); } @Override protected void createFormContent(IManagedForm mform) { final ScrolledForm mainForm = mform.getForm(); FormToolkit toolkit = new FormToolkit(mainForm.getDisplay()); Composite body = mainForm.getBody(); TableWrapLayout layout = new TableWrapLayout(); body.setLayout(layout); /* description panel */ Section descriptionSection = toolkit.createSection(body, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED ); descriptionSection.setText(Messages.DescriptionTitle); descriptionSection.setTitleBarForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE)); FormText descriptionText = toolkit.createFormText(descriptionSection, true); descriptionText.setText(Messages.SecureDescription, true, true); TableWrapData td = new TableWrapData(TableWrapData.FILL); td.colspan = 1; descriptionText.setLayoutData(td); descriptionSection.setClient(descriptionText); /* password panel */ String titleMsg; if (confirmPassword) titleMsg = Messages.PasswordChangeTitle; else if (passwordChange) titleMsg = Messages.MessageLoginChange; else titleMsg = Messages.DialogTitle; /* Separator */ toolkit.createLabel(body, ""); //$NON-NLS-1$ Section passwordSection = toolkit.createSection(body, ExpandableComposite.TITLE_BAR | ExpandableComposite.TWISTIE | ExpandableComposite.EXPANDED ); passwordSection.setText(titleMsg); passwordSection.setTitleBarForeground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_BLUE)); passwordSection.setLayoutData(td); Composite passwordComposite = toolkit.createComposite(passwordSection, SWT.NONE); GridLayoutFactory.fillDefaults().numColumns(2).applyTo(passwordComposite); Label passwordLabel = toolkit.createLabel(passwordComposite, Messages.LabelPassword, SWT.LEFT); GridDataFactory.swtDefaults().applyTo(passwordLabel); password = toolkit.createText(passwordComposite, "", SWT.LEFT | SWT.BORDER); //$NON-NLS-1$ GridDataFactory.fillDefaults().grab(true, false).applyTo(password); password.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { okButton.setEnabled(validatePassword(mainForm)); } }); /* This textbox has the focus on dialog display */ password.setFocus(); if (confirmPassword) { Label passwordConfLabel = toolkit.createLabel(passwordComposite, Messages.LabelConfirm, SWT.LEFT); GridDataFactory.swtDefaults().applyTo(passwordConfLabel); confirm = toolkit.createText(passwordComposite, "", SWT.LEFT | SWT.BORDER); //$NON-NLS-1$ GridDataFactory.fillDefaults().grab(true, false).applyTo(confirm); confirm.addModifyListener(new ModifyListener() { public void modifyText(ModifyEvent event) { okButton.setEnabled(validatePassword(mainForm)); } }); } else confirm = null; Label fillerLabel = toolkit.createLabel(passwordComposite, "", SWT.LEFT);// filler //$NON-NLS-1$ GridDataFactory.swtDefaults().applyTo(fillerLabel); showPassword = toolkit.createButton(passwordComposite, Messages.ShowPassword, SWT.CHECK | SWT.RIGHT); GridDataFactory.fillDefaults().align(SWT.RIGHT, SWT.CENTER).applyTo(showPassword); showPassword.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { passwordVisibility(); } public void widgetDefaultSelected(SelectionEvent e) { passwordVisibility(); } }); // by default don't display password as clear text showPassword.setSelection(false); passwordVisibility(); if (location != null) { Group locationGroup = new Group(passwordComposite, SWT.NONE); locationGroup.setText(Messages.LocationGroup); toolkit.adapt(locationGroup); GridDataFactory.fillDefaults().grab(true, true).span(2, 1).applyTo(locationGroup); GridLayoutFactory.fillDefaults().applyTo(locationGroup); Label locationLabel = toolkit.createLabel(locationGroup, new Path(location).toOSString(), SWT.WRAP); GridDataFactory.fillDefaults().grab(true, false).applyTo(locationLabel); } passwordSection.setClient(passwordComposite); /* Separator */ toolkit.createLabel(body, ""); //$NON-NLS-1$ /* Status label for any messages */ statusLabel = toolkit.createLabel(body, ""); //$NON-NLS-1$ TableWrapData td2 = new TableWrapData(TableWrapData.FILL); td2.colspan = 1; td2.grabHorizontal = true; statusLabel.setLayoutData(td2); statusLabel.setForeground(mainForm.getDisplay().getSystemColor(SWT.COLOR_RED)); } protected void passwordVisibility() { boolean selected = showPassword.getSelection(); if (selected) { password.setEchoChar('\0'); if (confirm != null) confirm.setEchoChar('\0'); } else { password.setEchoChar('*'); if (confirm != null) confirm.setEchoChar('*'); } } protected boolean validatePassword(ScrolledForm mainForm) { String password1 = password.getText(); if ((password1 == null) || (password1.length() == 0)) { statusLabel.setText(Messages.MessageEmptyPassword); return false; } if (confirm != null) { String password2 = confirm.getText(); if (!password1.equals(password2)) { statusLabel.setText(Messages.MessageNoMatch); return false; } } statusLabel.setText(""); //$NON-NLS-1$ return true; } @Override protected void okPressed() { String internalPassword; try { // normally use digest of what was entered MessageDigest digest = MessageDigest.getInstance(DIGEST_ALGORITHM); byte[] digested = digest.digest(new String(password.getText()).getBytes()); internalPassword = EncodingUtils.encodeBase64(digested); } catch (NoSuchAlgorithmException e) { // just use the text as is internalPassword = password.getText(); } generatedPassword = new PBEKeySpec(internalPassword.toCharArray()); super.okPressed(); } }