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 }