/******************************************************************************* * Copyright (c) 2011, 2013 Wind River Systems, Inc. and others. All rights reserved. * This program and the accompanying materials are 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: * Wind River Systems - initial API and implementation * Max Weninger (Wind River) - [361352] [TERMINALS][SSH] Add SSH terminal support *******************************************************************************/ package org.eclipse.tcf.te.ui.terminals.ssh.controls; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.Assert; 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.dialogs.IDialogSettings; import org.eclipse.swt.SWT; import org.eclipse.swt.events.TypedEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer; import org.eclipse.tcf.te.runtime.services.interfaces.constants.ITerminalsConnectorConstants; import org.eclipse.tcf.te.ui.controls.BaseDialogPageControl; import org.eclipse.tcf.te.ui.interfaces.data.IDataExchangeNode; import org.eclipse.tcf.te.ui.jface.interfaces.IValidatingContainer; import org.eclipse.tcf.te.ui.terminals.panels.AbstractConfigurationPanel; import org.eclipse.tcf.te.ui.terminals.ssh.nls.Messages; import org.eclipse.tm.internal.terminal.provisional.api.AbstractSettingsPage; import org.eclipse.tm.internal.terminal.provisional.api.ISettingsPage; import org.eclipse.tm.internal.terminal.ssh.SshConnector; import org.eclipse.tm.internal.terminal.ssh.SshSettings; import org.eclipse.ui.forms.widgets.FormToolkit; /** * SSH wizard configuration panel implementation. */ @SuppressWarnings("restriction") public class SshWizardConfigurationPanel extends AbstractConfigurationPanel implements IDataExchangeNode { private static final String SAVE_PASSWORD = "savePassword"; //$NON-NLS-1$ private SshSettings sshSettings; private ISettingsPage sshSettingsPage; private Button passwordButton; /** * Constructor. * * @param parentControl The parent control. Must not be null! */ public SshWizardConfigurationPanel(BaseDialogPageControl parentControl) { super(parentControl); } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel#setupPanel(org.eclipse.swt.widgets.Composite, org.eclipse.ui.forms.widgets.FormToolkit) */ @Override public void setupPanel(Composite parent, FormToolkit toolkit) { Composite panel = new Composite(parent, SWT.NONE); panel.setLayout(new GridLayout()); GridData data = new GridData(SWT.FILL, SWT.FILL, true, true); panel.setLayoutData(data); // Create the host selection combo if (isWithoutSelection()) createHostsUI(panel, true); SshConnector conn = new SshConnector(); sshSettings = (SshSettings) conn.getSshSettings(); sshSettings.setHost(getSelectionHost()); sshSettings.setUser(getDefaultUser()); sshSettingsPage = conn.makeSettingsPage(); if (sshSettingsPage instanceof AbstractSettingsPage) { ((AbstractSettingsPage)sshSettingsPage).setHasControlDecoration(true); } sshSettingsPage.createControl(panel); // Add the listener to the settings page if (getParentControl() instanceof IValidatingContainer) { sshSettingsPage.addListener(new ISettingsPage.Listener() { @Override public void onSettingsPageChanged(Control control) { ((IValidatingContainer)getParentControl()).validate(); } }); } // Create the encoding selection combo createEncodingUI(panel, true); // if password for host should be saved or no createPasswordUI(panel, true); setControl(panel); } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel#dataChanged(org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer, org.eclipse.swt.events.TypedEvent) */ @Override public boolean dataChanged(IPropertiesContainer data, TypedEvent e) { return false; } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.wizards.interfaces.ISharedDataExchangeNode#setupData(org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer) */ @Override public void setupData(IPropertiesContainer data) { if (data == null || sshSettings == null || sshSettingsPage == null) return; String value = data.getStringProperty(ITerminalsConnectorConstants.PROP_IP_HOST); if (value != null) sshSettings.setHost(value); value = data.getStringProperty(ITerminalsConnectorConstants.PROP_IP_PORT); if (value != null) sshSettings.setPort(value); value = data.getStringProperty(ITerminalsConnectorConstants.PROP_TIMEOUT); if (value != null) sshSettings.setTimeout(value); value = data.getStringProperty(ITerminalsConnectorConstants.PROP_SSH_KEEP_ALIVE); if (value != null) sshSettings.setKeepalive(value); value = data.getStringProperty(ITerminalsConnectorConstants.PROP_SSH_PASSWORD); if (value != null) sshSettings.setPassword(value); value = data.getStringProperty(ITerminalsConnectorConstants.PROP_SSH_USER); if (value != null) sshSettings.setUser(value); value = data.getStringProperty(ITerminalsConnectorConstants.PROP_ENCODING); if (value != null) setEncoding(value); sshSettingsPage.loadSettings(); } /** * Returns the default user name. * * @return The default user name. */ private String getDefaultUser(){ return System.getProperty("user.name"); //$NON-NLS-1$ } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.wizards.interfaces.ISharedDataExchangeNode#extractData(org.eclipse.tcf.te.runtime.interfaces.properties.IPropertiesContainer) */ @Override public void extractData(IPropertiesContainer data) { // set the terminal connector id for ssh data.setProperty(ITerminalsConnectorConstants.PROP_TERMINAL_CONNECTOR_ID, "org.eclipse.tm.internal.terminal.ssh.SshConnector"); //$NON-NLS-1$ // set the connector type for ssh data.setProperty(ITerminalsConnectorConstants.PROP_CONNECTOR_TYPE_ID, "org.eclipse.tcf.te.ui.terminals.type.ssh"); //$NON-NLS-1$ sshSettingsPage.saveSettings(); data.setProperty(ITerminalsConnectorConstants.PROP_IP_HOST,sshSettings.getHost()); data.setProperty(ITerminalsConnectorConstants.PROP_IP_PORT, sshSettings.getPort()); data.setProperty(ITerminalsConnectorConstants.PROP_TIMEOUT, sshSettings.getTimeout()); data.setProperty(ITerminalsConnectorConstants.PROP_SSH_KEEP_ALIVE, sshSettings.getKeepalive()); data.setProperty(ITerminalsConnectorConstants.PROP_SSH_PASSWORD, sshSettings.getPassword()); data.setProperty(ITerminalsConnectorConstants.PROP_SSH_USER, sshSettings.getUser()); data.setProperty(ITerminalsConnectorConstants.PROP_ENCODING, getEncoding()); } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.terminals.panels.AbstractConfigurationPanel#fillSettingsForHost(java.lang.String) */ @Override protected void fillSettingsForHost(String host){ boolean savePassword = false; if (host != null && host.length() != 0){ if (hostSettingsMap.containsKey(host)){ Map hostSettings = hostSettingsMap.get(host); if (hostSettings.get(ITerminalsConnectorConstants.PROP_IP_HOST) != null) { sshSettings.setHost(hostSettings.get(ITerminalsConnectorConstants.PROP_IP_HOST)); } if (hostSettings.get(ITerminalsConnectorConstants.PROP_IP_PORT) != null) { sshSettings.setPort(hostSettings.get(ITerminalsConnectorConstants.PROP_IP_PORT)); } if (hostSettings.get(ITerminalsConnectorConstants.PROP_TIMEOUT) != null) { sshSettings.setTimeout(hostSettings.get(ITerminalsConnectorConstants.PROP_TIMEOUT)); } if (hostSettings.get(ITerminalsConnectorConstants.PROP_SSH_KEEP_ALIVE) != null) { sshSettings.setKeepalive(hostSettings.get(ITerminalsConnectorConstants.PROP_SSH_KEEP_ALIVE)); } if (hostSettings.get(ITerminalsConnectorConstants.PROP_SSH_USER) != null) { sshSettings.setUser(hostSettings.get(ITerminalsConnectorConstants.PROP_SSH_USER)); } if (hostSettings.get(SAVE_PASSWORD) != null) { savePassword = new Boolean(hostSettings.get(SAVE_PASSWORD)).booleanValue(); } if (!savePassword){ sshSettings.setPassword(""); //$NON-NLS-1$ } else { String password = accessSecurePassword(sshSettings.getHost()); if (password != null) { sshSettings.setPassword(password); } } String encoding = hostSettings.get(ITerminalsConnectorConstants.PROP_ENCODING); if (encoding == null || "null".equals(encoding)) encoding = "ISO-8859-1"; //$NON-NLS-1$ //$NON-NLS-2$ setEncoding(encoding); } else { sshSettings.setHost(getSelectionHost()); sshSettings.setUser(getDefaultUser()); savePassword = false; } // set settings in page sshSettingsPage.loadSettings(); passwordButton.setSelection(savePassword); } } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.controls.interfaces.IWizardConfigurationPanel#doSaveWidgetValues(org.eclipse.jface.dialogs.IDialogSettings, java.lang.String) */ @Override public void doSaveWidgetValues(IDialogSettings settings, String idPrefix) { saveSettingsForHost(true); super.doSaveWidgetValues(settings, idPrefix); } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.terminals.panels.AbstractConfigurationPanel#saveSettingsForHost(boolean) */ @Override protected void saveSettingsForHost(boolean add){ boolean savePassword = passwordButton.getSelection(); String host = getHostFromSettings(); if (host != null && host.length() != 0) { if (hostSettingsMap.containsKey(host)){ Map hostSettings = hostSettingsMap.get(host); hostSettings.put(ITerminalsConnectorConstants.PROP_IP_HOST, sshSettings.getHost()); hostSettings.put(ITerminalsConnectorConstants.PROP_IP_PORT, Integer.toString(sshSettings.getPort())); hostSettings.put(ITerminalsConnectorConstants.PROP_TIMEOUT, Integer.toString(sshSettings.getTimeout())); hostSettings.put(ITerminalsConnectorConstants.PROP_SSH_KEEP_ALIVE, Integer.toString(sshSettings.getKeepalive())); hostSettings.put(ITerminalsConnectorConstants.PROP_SSH_USER, sshSettings.getUser()); hostSettings.put(ITerminalsConnectorConstants.PROP_ENCODING, getEncoding()); hostSettings.put(SAVE_PASSWORD, Boolean.toString(savePassword)); if (savePassword && sshSettings.getPassword() != null && sshSettings.getPassword().length() != 0){ saveSecurePassword(host, sshSettings.getPassword()); } // maybe unchecked the password button - so try to remove a saved password - if any if (!savePassword){ removeSecurePassword(host); } } else if (add) { Map hostSettings = new HashMap(); hostSettings.put(ITerminalsConnectorConstants.PROP_IP_HOST, sshSettings.getHost()); hostSettings.put(ITerminalsConnectorConstants.PROP_IP_PORT, Integer.toString(sshSettings.getPort())); hostSettings.put(ITerminalsConnectorConstants.PROP_TIMEOUT, Integer.toString(sshSettings.getTimeout())); hostSettings.put(ITerminalsConnectorConstants.PROP_SSH_KEEP_ALIVE, Integer.toString(sshSettings.getKeepalive())); hostSettings.put(ITerminalsConnectorConstants.PROP_SSH_USER, sshSettings.getUser()); hostSettings.put(ITerminalsConnectorConstants.PROP_ENCODING, getEncoding()); hostSettings.put(SAVE_PASSWORD, Boolean.toString(savePassword)); hostSettingsMap.put(host, hostSettings); if (savePassword && sshSettings.getPassword() != null && sshSettings.getPassword().length() != 0){ saveSecurePassword(host, sshSettings.getPassword()); } } } } /** * Save the password to the secure storage. * * @param host The host. Must not be null. * @param password The password. Must not be null. */ private void saveSecurePassword(String host, String password) { Assert.isNotNull(host); Assert.isNotNull(password); // To access the secure storage, we need the preference instance ISecurePreferences preferences = SecurePreferencesFactory.getDefault(); if (preferences != null) { // Construct the secure preferences node key String nodeKey = "/Target Explorer SSH Password/" + host; //$NON-NLS-1$ ISecurePreferences node = preferences.node(nodeKey); if (node != null) { try { node.put("password", password, true); //$NON-NLS-1$ } catch (StorageException ex) { /* ignored on purpose */ } } } } /** * Reads the password from the secure storage. * * @param host The host. Must not be null. * @return The password or null. */ private String accessSecurePassword(String host) { Assert.isNotNull(host); // To access the secure storage, we need the preference instance ISecurePreferences preferences = SecurePreferencesFactory.getDefault(); if (preferences != null) { // Construct the secure preferences node key String nodeKey = "/Target Explorer SSH Password/" + host; //$NON-NLS-1$ ISecurePreferences node = preferences.node(nodeKey); if (node != null) { String password = null; try { password = node.get("password", null); //$NON-NLS-1$ } catch (StorageException ex) { /* ignored on purpose */ } return password; } } return null; } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.terminals.panels.AbstractConfigurationPanel#removeSecurePassword(java.lang.String) */ @Override protected void removeSecurePassword(String host) { Assert.isNotNull(host); // To access the secure storage, we need the preference instance ISecurePreferences preferences = SecurePreferencesFactory.getDefault(); if (preferences != null) { // Construct the secure preferences node key String nodeKey = "/Target Explorer SSH Password/" + host; //$NON-NLS-1$ ISecurePreferences node = preferences.node(nodeKey); if (node != null) { node.remove("password"); //$NON-NLS-1$ } } } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.controls.panels.AbstractWizardConfigurationPanel#isValid() */ @Override public boolean isValid(){ return isEncodingValid() && sshSettingsPage.validateSettings(); } /* (non-Javadoc) * @see org.eclipse.tcf.te.ui.terminals.panels.AbstractConfigurationPanel#getHostFromSettings() */ @Override protected String getHostFromSettings() { sshSettingsPage.saveSettings(); return sshSettings.getHost(); } private void createPasswordUI(final Composite parent, boolean separator) { Assert.isNotNull(parent); if (separator) { Label sep = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); sep.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); } Composite panel = new Composite(parent, SWT.NONE); GridLayout layout = new GridLayout(1, false); layout.marginHeight = 0; layout.marginWidth = 0; panel.setLayout(layout); panel.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)); passwordButton = new Button(panel, SWT.CHECK); passwordButton.setLayoutData(new GridData(SWT.FILL, SWT.RIGHT, true, false)); passwordButton.setText(Messages.SshWizardConfigurationPanel_savePasword); } }