blob: de2356f4e40341698eb3012bc473320232cb92b0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Varun Raval and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Varun Raval - initial API and implementation
*******************************************************************************/
package org.eclipse.ease.ui.sign;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.security.Security;
import java.security.UnrecoverableKeyException;
import java.util.ArrayList;
import java.util.Iterator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.ease.Logger;
import org.eclipse.ease.sign.PerformSignature;
import org.eclipse.ease.sign.ScriptSignatureException;
import org.eclipse.ease.tools.ResourceTools;
import org.eclipse.ease.ui.Activator;
import org.eclipse.ease.ui.Messages;
import org.eclipse.equinox.security.storage.ISecurePreferences;
import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
import org.eclipse.equinox.security.storage.StorageException;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
public class PerformBasicSignPage extends WizardPage {
private final GetInfo fGetInfo;
private Combo fKeyStoreFileCombo;
private List fAliasList;
private boolean fIsComplete = false;
protected ArrayList<String> fKeyStoreFileList;
/**
* @param getInfo
* provide instance of {@link GetInfo}
*/
protected PerformBasicSignPage(GetInfo getInfo) {
super(Messages.PerformBasicSignPage_enterProperties);
setTitle(Messages.PerformBasicSignPage_enterProperties);
setPageComplete(false);
fGetInfo = getInfo;
fKeyStoreFileList = new ArrayList<>();
}
@Override
public void createControl(Composite parent) {
final ScrolledComposite scrolledComposite = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
final Composite container = new Composite(scrolledComposite, SWT.NONE);
scrolledComposite.setContent(container);
final GridLayout layout = new GridLayout();
container.setLayout(layout);
layout.numColumns = 4;
layout.makeColumnsEqualWidth = false;
GridData gridData;
final Label keyStoreLabel = new Label(container, SWT.NONE);
keyStoreLabel.setText(Messages.PerformBasicSignPage_keyStoreLoc);
keyStoreLabel.setToolTipText(Messages.PerformBasicSignPage_enterKeyStoreLoc);
gridData = new GridData(SWT.LEFT, SWT.CENTER, false, true, 1, 1);
keyStoreLabel.setLayoutData(gridData);
fKeyStoreFileCombo = new Combo(container, SWT.BORDER | SWT.SINGLE);
gridData = new GridData(SWT.FILL, SWT.CENTER, true, true, 2, 1);
fKeyStoreFileCombo.setLayoutData(gridData);
final Button browseButton = new Button(container, SWT.NONE);
gridData = new GridData(SWT.LEFT, SWT.CENTER, false, true, 1, 1);
browseButton.setText(Messages.PerformBasicSignPage_browse);
browseButton.setLayoutData(gridData);
final Label aliasLabel = new Label(container, SWT.NONE);
aliasLabel.setText(Messages.PerformBasicSignPage_chooseAlias);
gridData = new GridData(SWT.LEFT, SWT.CENTER, false, true, 4, 1);
aliasLabel.setLayoutData(gridData);
fAliasList = new List(container, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.SINGLE);
gridData = new GridData(SWT.FILL, SWT.CENTER, true, true, 4, 1);
fAliasList.setLayoutData(gridData);
initialize();
browseButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
final FileDialog fd = new FileDialog(getShell(), SWT.OPEN);
fd.setText(Messages.PerformBasicSignPage_chooseKeystore);
final String selectedFile = fd.open();
if (selectedFile != null)
fKeyStoreFileCombo.setText(selectedFile);
}
});
fKeyStoreFileCombo.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
try {
final String selectedFile = fKeyStoreFileCombo.getText();
loadKeyStore(selectedFile);
} catch (final ScriptSignatureException ex) {
Logger.error(Activator.PLUGIN_ID, ex.getMessage(), ex.getCause() != null ? ex.getCause() : ex);
setErrorMessage(ex.getMessage());
reset();
}
}
});
fAliasList.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
fGetInfo.setAlias(fAliasList.getItem(fAliasList.getSelectionIndex()));
fIsComplete = true;
setPageComplete(true);
}
});
container.setSize(container.computeSize(600, SWT.DEFAULT));
setControl(scrolledComposite);
}
protected void initialize() {
final IPath iPath = Activator.getDefault().getStateLocation();
BufferedReader bReader = null;
try {
fKeyStoreFileCombo.removeAll();
bReader = new BufferedReader(new FileReader(iPath.append(GetInfo.KEYSTORE_SETTING_FILE).toString()));
while (bReader.ready()) {
final String line = bReader.readLine();
fKeyStoreFileCombo.add(line);
fKeyStoreFileList.add(line);
}
} catch (final FileNotFoundException e) {
Logger.error(Activator.PLUGIN_ID, e.getMessage(), e);
} catch (final IOException e) {
Logger.error(Activator.PLUGIN_ID, e.getMessage(), e);
} finally {
if (bReader != null) {
try {
bReader.close();
} catch (final IOException e) {
Logger.error(Activator.PLUGIN_ID, e.getMessage(), e);
}
}
}
}
/**
* Load keystore.
*
* @param selectedFile
* provide path of file in string format
* @throws ScriptSignatureException
* when keystore cannot be loaded
*/
protected void loadKeyStore(String selectedFile) throws ScriptSignatureException {
final ISecurePreferences preferences = SecurePreferencesFactory.getDefault();
final ISecurePreferences node = preferences.node(GetInfo.KEYTORE_ALIAS_NODE);
String pass = null;
final String provider = null;
InputStream inputStream = null;
try {
while (true) {
inputStream = ResourceTools.getInputStream(selectedFile);
if (inputStream != null) {
pass = node.get(selectedFile, null);
if (pass == null) {
final PasswordDialog passwordDialog = new PasswordDialog(getShell(), selectedFile, Messages.PerformBasicSignPage_keystorePwd);
if (passwordDialog.open() == Window.CANCEL) {
reset();
throw new ScriptSignatureException("Cannot load Keystore");
}
pass = passwordDialog.getPassword();
}
try {
final Iterator<String> typeList = Security.getAlgorithms("keystore").iterator();
while (typeList.hasNext()) {
try {
fGetInfo.setKeyStore(PerformSignature.loadKeyStore(inputStream, typeList.next(), provider, pass));
break;
} catch (final IOException e) {
Logger.error(Activator.PLUGIN_ID, e.getMessage(), e);
// last type is also not applicable
if (!typeList.hasNext())
throw new ScriptSignatureException("Cannot load keystore");
}
}
fGetInfo.setKeyStoreFile(selectedFile);
fGetInfo.setKeyStorePassword(pass);
setErrorMessage(null);
setMessage(Messages.PerformBasicSignPage_keystoreLoaded, SWT.OK);
if (fKeyStoreFileList.contains(selectedFile))
fKeyStoreFileList.remove(selectedFile);
fKeyStoreFileList.add(0, selectedFile);
fGetInfo.setKeyStoreFiles(fKeyStoreFileList);
// initialize alias list
fAliasList.removeAll();
for (final String alias : PerformSignature.getAliases(fGetInfo.getKeyStore()))
fAliasList.add(alias);
fAliasList.setFocus();
fAliasList.setSelection(0);
return;
} catch (final UnrecoverableKeyException e) {
// password is incorrect. Remove key from node and try again
pass = null;
node.remove(selectedFile);
setErrorMessage(Messages.PerformBasicSignPage_invalidPwd);
}
} else
throw new ScriptSignatureException("Cannot open Keystore from provided file");
}
} catch (final StorageException e) {
Logger.error(Activator.PLUGIN_ID, e.getMessage(), e);
reset();
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (final IOException e) {
Logger.error(Activator.PLUGIN_ID, e.getMessage(), e);
}
}
}
/**
* Resets the values of page.
*/
protected void reset() {
fKeyStoreFileCombo.clearSelection();
fKeyStoreFileCombo.deselectAll();
fAliasList.removeAll();
}
/**
* Used to know whether page is complete so that navigations buttons can reset.
*
* @return <code>true</code> if page is complete and <code>false</code> if page is not complete
*/
boolean canComplete() {
return fIsComplete;
}
}