00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 package org.objectweb.proactive.core.ssh;
00032
00033 import java.io.File;
00034 import java.io.FileInputStream;
00035 import java.io.IOException;
00036 import java.io.InputStream;
00037 import java.net.InetAddress;
00038 import java.util.Hashtable;
00039
00040 import org.apache.log4j.Logger;
00041 import org.objectweb.proactive.core.config.ProActiveConfiguration;
00042 import org.objectweb.proactive.core.util.log.Loggers;
00043 import org.objectweb.proactive.core.util.log.ProActiveLogger;
00044
00045 import com.jcraft.jsch.JSch;
00046 import com.jcraft.jsch.JSchException;
00047 import com.jcraft.jsch.Session;
00048
00049
00050 public class JSchSingleton {
00051 static Logger logger = ProActiveLogger.getLogger(Loggers.SSH);
00052
00053 private JSchSingleton() {
00054 }
00055
00056 static private Semaphore _sem = null;
00057
00058 static private Semaphore getSem() {
00059 if (_sem == null) {
00060 _sem = new Semaphore(1);
00061 }
00062 return _sem;
00063 }
00064
00069 static public void acquireLock() {
00070 Semaphore sem = getSem();
00071 sem.down();
00072 }
00073
00074 static public void releaseLock() {
00075 Semaphore sem = getSem();
00076 sem.up();
00077 }
00078
00079 static private JSch getJSch() {
00080 if (_jsch == null) {
00081 Hashtable<String, String> config = new Hashtable<String, String>();
00082 config.put("StrictHostKeyChecking", "no");
00083 JSch.setConfig(config);
00084 _jsch = new JSch();
00085 try {
00086 String hostfile = SshParameters.getSshKnownHostsFile();
00087 InputStream is = new FileInputStream(hostfile);
00088 _jsch.setKnownHosts(is);
00089 } catch (Exception e) {
00090 logger.fatal("SSH known_hosts, " +
00091 SshParameters.getSshKnownHostsFile() +
00092 ", file cannot be opened, SSH will not work", e);
00093 }
00094 try {
00095 String keydir = SshParameters.getSshKeyDirectory();
00096 logger.debug("read key dir: " + keydir);
00097 File parent = new File(keydir);
00098 if (!parent.exists() || !parent.isDirectory()) {
00099 logger.fatal("SSH key_directory, " + keydir +
00100 ", cannot be opened. SSH will not work");
00101 } else {
00102 String[] children = parent.list();
00103 for (int i = 0; i < children.length; i++) {
00104 String filename = children[i];
00105 if (filename.endsWith(".pub")) {
00106 String privKeyFilename = filename.substring(0,
00107 filename.length() - 4);
00108 File privKeyFile = new File(parent, privKeyFilename);
00109 if (privKeyFile.isFile() && privKeyFile.canRead()) {
00110 try {
00111 logger.debug("adding identity " +
00112 privKeyFile.getPath());
00113 _jsch.addIdentity(privKeyFile.getPath(),
00114 (String) null);
00115 } catch (Exception e) {
00116 e.printStackTrace();
00117 }
00118 }
00119 }
00120 }
00121 if (_jsch.getIdentityNames().size() == 0) {
00122 logger.info("No SSH private key found in " +
00123 SshParameters.getSshKeyDirectory());
00124 }
00125 }
00126 } catch (Exception e) {
00127 e.printStackTrace();
00128 }
00129 }
00130 return _jsch;
00131 }
00132
00133 static private JSch _jsch = null;
00134
00135 static public Session getSession(String username, String hostname,
00136 String sshPort) throws IOException {
00137 if (_hash == null) {
00138 _hash = new Hashtable<String, Session>();
00139 }
00140 String key = sshPort + username + hostname;
00141 Session val = _hash.get(key);
00142 Session session;
00143 if (val == null) {
00144 int port = Integer.parseInt(sshPort);
00145 try {
00146 session = getJSch().getSession(username, hostname, port);
00147 session.setUserInfo(new UserInfoNone());
00148 } catch (JSchException e) {
00149 throw new IOException(e.getMessage());
00150 }
00151 _hash.put(key, session);
00152 } else {
00153 session = val;
00154 }
00155 if (!session.isConnected()) {
00156 try {
00157 session.connect();
00158 } catch (JSchException e) {
00159 if (e.getMessage().indexOf("java.net.NoRouteToHostException") != -1) {
00160 logger.info("No route to host from " +
00161 InetAddress.getLocalHost().getHostName() + " to " +
00162 hostname + ":" + sshPort +
00163 "; please check your descriptor file.");
00164 if (ProActiveConfiguration.isForwarder()) {
00165 logger.info("Forwarding enabled." +
00166 " An internal IP is probably returned by a forwarder," +
00167 " you can fix this using internal_ip attribute");
00168 }
00169 } else {
00170 logger.info(e.getMessage() + " when connecting from " +
00171 InetAddress.getLocalHost().getHostName() + "to " +
00172 hostname + ":" + sshPort);
00173 throw new IOException(e.getMessage());
00174 }
00175 }
00176 }
00177 return session;
00178 }
00179
00180 static private Hashtable<String, Session> _hash = null;
00181
00182 static public void flushMaybe(String username, String hostname,
00183 String sshPort, int localPort) {
00184 String key = sshPort + username + hostname;
00185 Session val = _hash.get(key);
00186 if (val == null) {
00187 return;
00188 }
00189 Session session = val;
00190 try {
00191 session.delPortForwardingL(localPort);
00192 int nForward = session.getPortForwardingL().length;
00193 if (nForward == 0) {
00194 _hash.remove(key);
00195 session.disconnect();
00196 }
00197 } catch (JSchException e) {
00198 e.printStackTrace();
00199 }
00200 }
00201 }