package org.zend.php.zendserver.deployment.core.targets; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.Status; import org.eclipse.jsch.internal.core.IConstants; import org.eclipse.jsch.internal.core.JSchCorePlugin; import org.zend.php.zendserver.deployment.core.DeploymentCore; import org.zend.php.zendserver.deployment.core.Messages; import com.jcraft.jsch.JSch; import com.jcraft.jsch.JSchException; import com.jcraft.jsch.KeyPairRSA; public class EclipseSSH2Settings { public static final String RSA = IConstants.RSA; public static final String SSH_PRIVATE_KEY_PATH = "ssh-private-key"; //$NON-NLS-1$ private static final String KEY_NAME_SEPARATOR = ","; //$NON-NLS-1$ public static File getPrivateKey(String type) { Preferences preferences = JSchCorePlugin.getPlugin() .getPluginPreferences(); String ssh2Home = preferences.getString(IConstants.KEY_SSH2HOME); return new File(ssh2Home, "id_rsa"); //$NON-NLS-1$ } public static void createPrivateKey(String type, String path) throws CoreException { Assert.isTrue(RSA.equals(type)); JSch jsch = JSchCorePlugin.getPlugin().getJSch(); KeyPairRSA pair = new KeyPairRSA(jsch); com.jcraft.jsch.KeyPair pk; try { pk = pair.genKeyPair(jsch, com.jcraft.jsch.KeyPair.RSA); } catch (JSchException e) { throw new CoreException(new Status(IStatus.ERROR, DeploymentCore.PLUGIN_ID, e.getMessage(), e)); } File dir = new File(path).getParentFile(); if (!dir.exists()) { boolean success = dir.mkdirs(); if (!success) { throw new CoreException(new Status(IStatus.ERROR, DeploymentCore.PLUGIN_ID, Messages.bind( Messages.EclipseSSH2Settings_CreateFileError, new Object[] { path, dir }))); } } try { pk.writePrivateKey(new FileOutputStream(path)); } catch (FileNotFoundException e) { throw new CoreException(new Status(IStatus.ERROR, DeploymentCore.PLUGIN_ID, e.getMessage(), e)); } } /** * Copies SSH key file to Eclipse SSH home * * @param keyPath existing key * @param newNameHint hint to use when inventing new key name * @param overwrite * @return copied key full path * * @throws IOException */ private static String copySSHKey(String keyPath, String newNameHint, boolean overwrite) throws IOException { Preferences preferences = JSchCorePlugin.getPlugin() .getPluginPreferences(); String ssh2Home = preferences.getString(IConstants.KEY_SSH2HOME); String existingPrivateKeys = preferences.getString(IConstants.KEY_PRIVATEKEY); List<String> existingKeys = Arrays.asList(existingPrivateKeys.split(KEY_NAME_SEPARATOR)); File keyFile; keyFile = new File(keyPath); String keyName = keyFile.getName(); String parent = keyFile.getParent(); if (parent != null && parent.equals(ssh2Home)) { if (existingKeys.contains(keyName)) { return keyPath; // key already exists in ssh2Home and is on private keys list } else { // key is already in ssh2Home, so we'll only add it to the list (later below) } } else { if (existingKeys.contains(keyName) && !overwrite) { keyName = newNameHint; if (existingKeys.contains(keyName)) { int i = 1; do { keyName = newNameHint + i++; } while (existingKeys.contains(keyName)); } } // key is in external directory. Let's copy it to ssh2Home File newKeyFile = new File(ssh2Home, keyName); copyFile(keyFile, newKeyFile); keyFile = newKeyFile; // if key is already on the list do not add it again if (existingKeys.contains(keyName) && overwrite) { return newKeyFile.toString(); } } existingPrivateKeys = existingPrivateKeys + KEY_NAME_SEPARATOR + keyFile.getName(); preferences.setValue(IConstants.KEY_PRIVATEKEY, existingPrivateKeys); JSchCorePlugin.getPlugin().setNeedToLoadKnownHosts(true); JSchCorePlugin.getPlugin().setNeedToLoadKeys(true); JSchCorePlugin.getPlugin().savePluginPreferences(); return keyFile.toString(); } private static void copyFile(File srcFile, File destFile) throws IOException { File dir = destFile.getParentFile(); if (!dir.exists()) { boolean success = dir.mkdirs(); if (!success) { throw new IOException(Messages.bind( Messages.EclipseSSH2Settings_CopyFileError, new Object[] { srcFile, destFile, dir })); } } FileOutputStream fos = new FileOutputStream(destFile); FileInputStream fis = new FileInputStream(srcFile); byte[] buf = new byte[4096]; int len; try { while ((len = fis.read(buf)) != -1) { fos.write(buf, 0, len); } } finally { fos.close(); fis.close(); } } public static String getSSHHome() { Preferences preferences = JSchCorePlugin.getPlugin() .getPluginPreferences(); return preferences.getString(IConstants.KEY_SSH2HOME); } }