|
From: <ha...@us...> - 2007-11-23 21:24:50
|
Revision: 1840
http://cogkit.svn.sourceforge.net/cogkit/?rev=1840&view=rev
Author: hategan
Date: 2007-11-23 13:24:48 -0800 (Fri, 23 Nov 2007)
Log Message:
-----------
new ssh stuff
Added Paths:
-----------
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/ConnectionID.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/CredentialsDialog.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/InteractiveSSHSecurityContextImpl.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHChannel.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHChannelManager.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHConnectionBundle.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHRunner.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHSecurityContextImpl.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHTask.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHTaskStatusListener.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/Ssh.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/execution/
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/execution/DelegatedTaskHandlerFactory.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/execution/Exec.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/execution/FileTransferTaskHandler.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/execution/JobSubmissionTaskHandler.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/execution/OutputListener.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/execution/Sftp.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/execution/TaskHandlerImpl.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/file/
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/file/FileResourceImpl.java
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/file/TaskHandlerImpl.java
Removed Paths:
-------------
trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/execution/
Added: trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/ConnectionID.java
===================================================================
--- trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/ConnectionID.java (rev 0)
+++ trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/ConnectionID.java 2007-11-23 21:24:48 UTC (rev 1840)
@@ -0,0 +1,51 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Nov 20, 2007
+ */
+package org.globus.cog.abstraction.impl.ssh;
+
+public class ConnectionID {
+ public String host;
+ public int port;
+ public Object credentials;
+
+ public ConnectionID(String host, int port, Object credentials) {
+ this.host = host;
+ this.port = port;
+ this.credentials = credentials;
+ }
+
+ public boolean equals(Object obj) {
+ if (obj instanceof ConnectionID) {
+ ConnectionID other = (ConnectionID) obj;
+ return eq(host, other.host) && port == other.port
+ && eq(credentials, other.credentials);
+ }
+ else {
+ return false;
+ }
+ }
+
+ private boolean eq(Object o1, Object o2) {
+ if (o1 == null) {
+ return o2 == null;
+ }
+ else {
+ return o1.equals(o2);
+ }
+ }
+
+ public int hashCode() {
+ return (host == null ? 0 : host.hashCode()) + port
+ + (credentials == null ? 0 : credentials.hashCode());
+ }
+
+ public String toString() {
+ return credentials + "@" + host + ":" + port;
+ }
+}
\ No newline at end of file
Added: trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/CredentialsDialog.java
===================================================================
--- trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/CredentialsDialog.java (rev 0)
+++ trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/CredentialsDialog.java 2007-11-23 21:24:48 UTC (rev 1840)
@@ -0,0 +1,347 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+package org.globus.cog.abstraction.impl.ssh;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GraphicsEnvironment;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.PasswordAuthentication;
+import java.util.Arrays;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+
+import org.globus.cog.abstraction.impl.common.PublicKeyAuthentication;
+
+public abstract class CredentialsDialog {
+ private static final String NOTHING = "";
+ private static final String SSH_HOME = System.getProperty("user.home") + File.separator
+ + ".ssh";
+
+ protected String userName, privateKey;
+
+ public String getPrivateKey() {
+ return privateKey;
+ }
+
+ public void setPrivateKey(String privatekey) {
+ this.privateKey = privatekey;
+ }
+
+ public String getUserName() {
+ return userName;
+ }
+
+ public void setUserName(String username) {
+ this.userName = username;
+ }
+
+ public abstract Object getResult();
+
+ public static Object showCredentialsDialog() {
+ return showCredentialsDialog(null, null);
+ }
+
+ public static Object showCredentialsDialog(String userName, String privateKey) {
+ return showCredentialsDialog(userName, privateKey, false);
+ }
+
+ public static Object showCredentialsDialog(String userName, String privateKey,
+ boolean forceTextMode) {
+ CredentialsDialog cd;
+ try {
+ if (GraphicsEnvironment.isHeadless() || forceTextMode) {
+ cd = new ConsoleCredentialsDialog();
+ }
+ else {
+ cd = new SwingCredentialsDialog();
+ }
+ }
+ catch (Exception e) {
+ cd = new ConsoleCredentialsDialog();
+ }
+ if (userName != null) {
+ cd.setUserName(userName);
+ }
+ if (privateKey != null) {
+ cd.setPrivateKey(privateKey);
+ }
+ return cd.getResult();
+ }
+
+ public static class SwingCredentialsDialog extends CredentialsDialog {
+ private JOptionPane optionPane = new JOptionPane();
+ private JDialog dialog;
+
+ private JLabel passwordLabel;
+ private JTextField usernameField = new JTextField();
+ private JPasswordField passwordField = new JPasswordField();
+ private JTextField privateKeyField = new JTextField();
+
+ private JButton choosePathButton = new JButton("Browse");
+
+ public SwingCredentialsDialog() {
+ // init sizes
+ usernameField.setPreferredSize(new Dimension(125, 20));
+ passwordField.setPreferredSize(new Dimension(125, 20));
+ privateKeyField.setPreferredSize(new Dimension(150, 20));
+
+ // the main panel
+ JPanel main = new JPanel(new BorderLayout());
+
+ // Labels
+ JPanel labels = new JPanel(new GridLayout(0, 1));
+ labels.add(new JLabel("Username: "));
+ labels.add(passwordLabel = new JLabel("Password: "));
+ JLabel pkLabel = new JLabel("Private Key: ");
+ pkLabel.setToolTipText("Your private key if needed, else leave blank");
+ labels.add(pkLabel);
+
+ // username and password labels/fields
+ JPanel fields = new JPanel(new GridLayout(0, 1));
+ fields.add(usernameField);
+ fields.add(passwordField);
+
+ // path to the private key field/button
+ JPanel pKeyPanel = new JPanel(new BorderLayout());
+ privateKeyField.setToolTipText("Your private key if needed, else leave blank");
+ pKeyPanel.add(privateKeyField, BorderLayout.CENTER);
+ pKeyPanel.add(choosePathButton, BorderLayout.EAST);
+
+ // add an action listener
+ choosePathButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent aEvent) {
+ choosePathToPrivateKey();
+ }
+ });
+
+ fields.add(pKeyPanel);
+
+ main.add(labels, BorderLayout.WEST);
+ main.add(fields, BorderLayout.CENTER);
+
+ optionPane.setMessage(main);
+ optionPane.setOptionType(JOptionPane.OK_CANCEL_OPTION);
+ dialog = optionPane.createDialog(null, "Enter Your SSH Credentials");
+ }
+
+ protected void choosePathToPrivateKey() {
+ JFileChooser fileChooser = new JFileChooser(SSH_HOME);
+ fileChooser.setFileHidingEnabled(false);
+ int returnVal = fileChooser.showOpenDialog(optionPane);
+ if (returnVal == JFileChooser.APPROVE_OPTION) {
+ setPrivateKeyFieldText(fileChooser.getSelectedFile().getAbsolutePath());
+ }
+ }
+
+ protected synchronized Object okButtonPushed() {
+ String uname = usernameField.getText();
+ char[] passwd = passwordField.getPassword();
+ String pKeyPath = privateKeyField.getText();
+
+ if (NOTHING.equals(uname) && NOTHING.equals(passwd) && NOTHING.equals(pKeyPath)) {
+ return null;
+ }
+ else if (passwd == null) { // prevent null pointers
+ return null;
+ }
+ else if (NOTHING.equals(pKeyPath)) {
+ return new PasswordAuthentication(uname, passwd);
+ }
+ else {
+ return new PublicKeyAuthentication(uname, pKeyPath, passwd);
+ }
+ }
+
+ public Object getResult() {
+ dialog.setVisible(true);
+ if (optionPane.getValue() != null
+ && ((Integer) optionPane.getValue()).equals(new Integer(JOptionPane.OK_OPTION))) {
+ return okButtonPushed();
+ }
+ else {
+ return null;
+ }
+ }
+
+ public void setPrivateKey(String privatekey) {
+ super.setPrivateKey(privatekey);
+ setPrivateKeyFieldText(privatekey);
+ }
+
+ private void setPrivateKeyFieldText(String privateKey) {
+ privateKeyField.setText(privateKey);
+ if (privateKey == null || privateKey.equals("")) {
+ passwordLabel.setText("Password: ");
+ }
+ else {
+ passwordLabel.setText("Passphrase: ");
+ }
+ }
+
+ public void setUserName(String username) {
+ super.setUserName(username);
+ usernameField.setText(username);
+ if (username != null) {
+ passwordField.requestFocus();
+ }
+ }
+
+ }
+
+ public static class ConsoleCredentialsDialog extends CredentialsDialog {
+ public String TAB = "\t";
+ public static final int MAX_MASKED_CHARS = 80;
+
+ public Object getResult() {
+ if (userName == null) {
+ System.out.print("Username: ");
+ userName = input();
+ }
+ else {
+ System.out.println("Username: " + userName);
+ }
+ if (privateKey == null) {
+ System.out.println("Empty password for public key authentication.");
+ System.out.print("Password: ");
+ char[] tmp = inputMasked();
+ if (tmp.length == 0) {
+ for (int i = 0; i < 80; i++) {
+ System.out.print('\b');
+ }
+ String defaultPK = getDefaultPrivateKey();
+ System.out.println("Private key file ["+defaultPK+"]: ");
+ privateKey = input();
+ if (privateKey == null || privateKey.equals("")) {
+ privateKey = defaultPK;
+ }
+ System.out.print("Passphrase: ");
+ return new PublicKeyAuthentication(userName, privateKey, inputMasked());
+ }
+ else {
+ return new PasswordAuthentication(userName, tmp);
+ }
+ }
+ else {
+ System.out.println("Private key: " + privateKey);
+ System.out.print("Passphrase: ");
+ return new PublicKeyAuthentication(userName, privateKey, inputMasked());
+ }
+ }
+
+ protected String getDefaultPrivateKey() {
+ File pk;
+ pk = new File(SSH_HOME, "identity");
+ if (pk.exists()) {
+ return pk.getAbsolutePath();
+ }
+ pk = new File(SSH_HOME);
+ if (pk.exists()) {
+ return pk.getAbsolutePath();
+ }
+ return "";
+ }
+
+ protected String input() {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ try {
+ return br.readLine();
+ }
+ catch (IOException e) {
+ return "";
+ }
+ }
+
+ protected synchronized char[] inputMasked() {
+ char[] buf = new char[MAX_MASKED_CHARS];
+ int crt = 0;
+ char c;
+ ConsoleMasker.startMasking();
+ while (crt < MAX_MASKED_CHARS) {
+ try {
+ c = (char) System.in.read();
+ if (c == '\n') {
+ break;
+ }
+ else {
+ buf[crt++] = c;
+ }
+ }
+ catch (IOException e) {
+ break;
+ }
+ }
+ ConsoleMasker.stopMasking();
+ char[] in = new char[crt];
+ System.arraycopy(buf, 0, in, 0, crt);
+ Arrays.fill(buf, '\0');
+ return in;
+ }
+ }
+
+ public static class ConsoleMasker extends Thread {
+ private static ConsoleMasker masker;
+ private volatile boolean done;
+
+ public synchronized static void startMasking() {
+ if (masker != null) {
+ throw new IllegalStateException("Another maskeing thread");
+ }
+ masker = new ConsoleMasker();
+ masker.start();
+ }
+
+ public synchronized static void stopMasking() {
+ if (masker == null) {
+ throw new IllegalStateException("No masking thread is active");
+ }
+ masker.done();
+ masker = null;
+ }
+
+ public ConsoleMasker() {
+ this.setPriority(Thread.MAX_PRIORITY);
+ this.setName("Console Masking");
+ }
+
+ public void run() {
+ System.out.print(' ');
+ char crt = ' ';
+ while (!done) {
+ System.out.print('\b');
+ System.out.print(crt++);
+ System.out.flush();
+ if (crt == 127) {
+ crt = ' ';
+ }
+ try {
+ Thread.sleep(1);
+ }
+ catch (InterruptedException e) {
+ return;
+ }
+ }
+ }
+
+ private void done() {
+ done = true;
+ }
+ }
+}
\ No newline at end of file
Added: trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/InteractiveSSHSecurityContextImpl.java
===================================================================
--- trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/InteractiveSSHSecurityContextImpl.java (rev 0)
+++ trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/InteractiveSSHSecurityContextImpl.java 2007-11-23 21:24:48 UTC (rev 1840)
@@ -0,0 +1,72 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+package org.globus.cog.abstraction.impl.ssh;
+
+import java.net.PasswordAuthentication;
+import java.util.Hashtable;
+
+import org.apache.log4j.Logger;
+import org.globus.cog.abstraction.interfaces.SecurityContext;
+
+public class InteractiveSSHSecurityContextImpl implements SecurityContext {
+
+ private static Logger logger = Logger.getLogger(InteractiveSSHSecurityContextImpl.class.getName());
+ private Object credentials;
+
+ private Hashtable attributes = new Hashtable();
+
+ public InteractiveSSHSecurityContextImpl() {
+ // this.credentials = new PasswordAuthentication(null, null);
+ }
+
+ public InteractiveSSHSecurityContextImpl(Object credentials) {
+ setCredentials(credentials);
+ }
+
+ public void setCredentials(Object credentials, String alias) {
+ setCredentials(credentials);
+ }
+
+ public void setCredentials(Object credentials) {
+ this.credentials = credentials;
+ }
+
+ public synchronized Object getCredentials() {
+ if (credentials == null) {
+ boolean forceText = false;
+ Object text = getAttribute("nogui");
+ if (text != null
+ && (Boolean.TRUE.equals(text) || (text instanceof String && Boolean.valueOf(
+ (String) text).booleanValue()))) {
+ forceText = true;
+ }
+ credentials = CredentialsDialog.showCredentialsDialog(
+ (String) getAttribute("username"), (String) getAttribute("privatekey"), forceText);
+ if (credentials == null) {
+ // Cancel was pressed, so we set it to mock credentials to
+ // avoid being asked again
+ credentials = new PasswordAuthentication("", new char[0]);
+ }
+ }
+ return this.credentials;
+ }
+
+ public void setAttribute(String name, Object value) {
+ this.attributes.put(name, value);
+ }
+
+ public Object getAttribute(String name) {
+ return this.attributes.get(name);
+ }
+
+ public void setAlias(String alias) {
+ }
+
+ public String getAlias() {
+ return null;
+ }
+}
Added: trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHChannel.java
===================================================================
--- trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHChannel.java (rev 0)
+++ trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHChannel.java 2007-11-23 21:24:48 UTC (rev 1840)
@@ -0,0 +1,38 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Nov 20, 2007
+ */
+package org.globus.cog.abstraction.impl.ssh;
+
+import com.sshtools.j2ssh.session.SessionChannelClient;
+
+public class SSHChannel {
+ private Ssh connection;
+ private SessionChannelClient session;
+ private SSHConnectionBundle bundle;
+
+ public SSHChannel(SSHConnectionBundle bundle, Ssh connection, SessionChannelClient session) {
+ this.connection = connection;
+ this.session = session;
+ this.bundle = bundle;
+ }
+
+ public Ssh getSsh() {
+ return connection;
+ }
+
+ public SessionChannelClient getSession() {
+ return session;
+ }
+
+ public SSHConnectionBundle getBundle() {
+ return bundle;
+ }
+
+
+}
Added: trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHChannelManager.java
===================================================================
--- trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHChannelManager.java (rev 0)
+++ trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHChannelManager.java 2007-11-23 21:24:48 UTC (rev 1840)
@@ -0,0 +1,204 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Nov 19, 2007
+ */
+package org.globus.cog.abstraction.impl.ssh;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.PasswordAuthentication;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import org.apache.log4j.Logger;
+import org.globus.cog.abstraction.impl.common.PublicKeyAuthentication;
+import org.globus.cog.abstraction.impl.common.task.IllegalSpecException;
+import org.globus.cog.abstraction.impl.common.task.InvalidSecurityContextException;
+import org.globus.cog.abstraction.impl.common.task.InvalidServiceContactException;
+import org.globus.cog.abstraction.impl.common.task.TaskSubmissionException;
+
+public class SSHChannelManager {
+ public static final Logger logger = Logger
+ .getLogger(SSHChannelManager.class);
+
+ public static final long REAP_INTERVAL = 10 * 1000;
+
+ private static SSHChannelManager defaultManager;
+
+ static {
+ defaultManager = new SSHChannelManager();
+ }
+
+ public static SSHChannelManager getDefault() {
+ return defaultManager;
+ }
+
+ private Map bundles;
+ private Reaper reaper;
+
+ public SSHChannelManager() {
+ bundles = new HashMap();
+ reaper = new Reaper();
+ reaper.start();
+ }
+
+ public SSHChannel getChannel(String host, int port, Object credentials)
+ throws InvalidSecurityContextException, IllegalSpecException,
+ InvalidServiceContactException, TaskSubmissionException {
+ if (port == -1) {
+ port = 22;
+ }
+ ConnectionID i = new ConnectionID(host, port, getCredentials(credentials, host));
+ SSHConnectionBundle bundle = null;
+ synchronized (bundles) {
+ bundle = (SSHConnectionBundle) bundles.get(i);
+ if (bundle == null) {
+ bundle = new SSHConnectionBundle(i);
+ bundles.put(i, bundle);
+ }
+ }
+ return bundle.allocateChannel();
+ }
+
+ private static final char[] NO_PASSPHRASE = new char[0];
+
+ public static Object getCredentials(Object credentials, String host)
+ throws InvalidSecurityContextException {
+ if (credentials == null) {
+ credentials = getDefaultCredentials(host);
+ }
+ if (credentials instanceof PasswordAuthentication) {
+ return credentials;
+ }
+ else if (credentials instanceof PublicKeyAuthentication) {
+ return credentials;
+ }
+ else if (credentials == null) {
+ throw new InvalidSecurityContextException(
+ "No credentials specified and no entry found in "
+ + getAuthFilePath() + " for " + host);
+ }
+ else {
+ throw new InvalidSecurityContextException(
+ "Unsupported credentials: " + credentials);
+ }
+ }
+
+ public void releaseChannel(SSHChannel s) {
+ s.getBundle().releaseChannel(s);
+ }
+
+ private static Map credentials;
+ private static long lastLoad;
+ public static final String CREDENTIALS_FILE = "auth.defaults";
+
+ static {
+ credentials = new HashMap();
+ }
+
+ private static String getAuthFilePath() {
+ return System.getProperty("user.home") + File.separator + ".ssh"
+ + File.separator + CREDENTIALS_FILE;
+ }
+
+ public static Object getDefaultCredentials(String host) {
+ File f = new File(getAuthFilePath());
+ if (f.exists()) {
+ if (lastLoad < f.lastModified()) {
+ try {
+ loadDefaultCredentials(f);
+ }
+ catch (IOException e) {
+ logger.warn("Failed to load default credentials file", e);
+ }
+ }
+ synchronized (credentials) {
+ return credentials.get(host);
+ }
+ }
+ else {
+ return null;
+ }
+ }
+
+ public static void loadDefaultCredentials(File f) throws IOException {
+ synchronized (credentials) {
+ credentials.clear();
+ Properties p = new Properties();
+ p.load(new FileInputStream(f));
+ Iterator i = p.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry e = (Map.Entry) i.next();
+ String key = (String) e.getKey();
+ String val = (String) e.getValue();
+ if (key.endsWith(".type")) {
+ String host = key.substring(0, key.length() - 5);
+ String username = p.getProperty(host + ".username");
+ if (username == null) {
+ username = System.getProperty("user.name");
+ }
+ Object auth = null;
+ if ("password".equals(val)) {
+ String password = p.getProperty(host + ".password");
+ auth = new PasswordAuthentication(username, password
+ .toCharArray());
+ }
+ else if ("key".equals(val)) {
+ String pkey = p.getProperty(host + ".key");
+ String passphrase = p.getProperty(host + ".passphrase");
+ auth = new PublicKeyAuthentication(username, pkey,
+ passphrase.toCharArray());
+ }
+ else {
+ logger.warn("Unknown authentication type for \"" + host
+ + "\": " + val);
+ }
+ credentials.put(host, auth);
+ }
+ }
+ lastLoad = System.currentTimeMillis();
+ }
+ }
+
+ private class Reaper extends Thread {
+ public Reaper() {
+ super("SSH Channel Reaper");
+ setDaemon(true);
+ }
+
+ public void run() {
+ try {
+ List shutdown = new ArrayList();
+ while (true) {
+ shutdown.clear();
+ Thread.sleep(REAP_INTERVAL);
+ synchronized (bundles) {
+ Iterator i = bundles.entrySet().iterator();
+ while (i.hasNext()) {
+ Map.Entry e = (Entry) i.next();
+ ConnectionID ix = (ConnectionID) e.getKey();
+ SSHConnectionBundle bundle = (SSHConnectionBundle) e.getValue();
+ if (!bundle.shutdownIdleConnections()) {
+ i.remove();
+ }
+ }
+ }
+ }
+ }
+ catch (InterruptedException e) {
+
+ }
+ }
+ }
+}
Added: trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHConnectionBundle.java
===================================================================
--- trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHConnectionBundle.java (rev 0)
+++ trunk/current/src/cog/modules/provider-ssh/src/org/globus/cog/abstraction/impl/ssh/SSHConnectionBundle.java 2007-11-23 21:24:48 UTC (rev 1840)
@@ -0,0 +1,254 @@
+//----------------------------------------------------------------------
+//This code is developed as part of the Java CoG Kit project
+//The terms of the license can be found at http://www.cogkit.org/license
+//This message may not be removed or altered.
+//----------------------------------------------------------------------
+
+/*
+ * Created on Nov 20, 2007
+ */
+package org.globus.cog.abstraction.impl.ssh;
+
+import java.io.IOException;
+import java.net.PasswordAuthentication;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.globus.cog.abstraction.impl.common.PublicKeyAuthentication;
+import org.globus.cog.abstraction.impl.common.task.InvalidSecurityContextException;
+import org.globus.cog.abstraction.impl.common.task.InvalidServiceContactException;
+import org.globus.cog.abstraction.impl.common.task.TaskSubmissionException;
+
+public class SSHConnectionBundle {
+ public static final Logger logger = Logger
+ .getLogger(SSHConnectionBundle.class);
+
+ public static final long MAX_IDLE_TIME = 60 * 1000;
+ public static final int MAX_SESSIONS_PER_CONNECTION = 10;
+ public static final int MAX_CONCURRENT_CONNECTIONS = 10;
+
+ private List connections;
+ private ConnectionID id;
+ private Object credentials;
+ private int connecting;
+
+ public SSHConnectionBundle(ConnectionID id) {
+ this.id = id;
+ connections = new ArrayList();
+ if (logger.isDebugEnabled()) {
+ logger.debug("New SSH connection bundle: " + id);
+ }
+ }
+
+ public ConnectionID getId() {
+ return id;
+ }
+
+ public Object getCredentials() {
+ return credentials;
+ }
+
+ public void setCredentials(Object credentials) {
+ this.credentials = credentials;
+ }
+
+ public SSHChannel allocateChannel() throws InvalidSecurityContextException,
+ InvalidServiceContactException, TaskSubmissionException {
+ Connection connection = null;
+ synchronized (connections) {
+ Iterator i = connections.iterator();
+ while (i.hasNext()) {
+ Connection c = (Connection) i.next();
+ if (c.sessionCount < MAX_SESSIONS_PER_CONNECTION) {
+ connection = c;
+ break;
+ }
+ }
+ if (connection == null) {
+ connection = newConnection();
+ connections.add(connection);
+ }
+ connection.sessionCount++;
+ }
+ try {
+ connection.ensureConnected();
+ }
+ catch (Exc...
[truncated message content] |