org/objectweb/proactive/core/ssh/JSchSingleton.java

00001 /*
00002  * ################################################################
00003  *
00004  * ProActive: The Java(TM) library for Parallel, Distributed,
00005  *            Concurrent computing with Security and Mobility
00006  *
00007  * Copyright (C) 1997-2007 INRIA/University of Nice-Sophia Antipolis
00008  * Contact: proactive@objectweb.org
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
00023  * USA
00024  *
00025  *  Initial developer(s):               The ProActive Team
00026  *                        http://www.inria.fr/oasis/ProActive/contacts.html
00027  *  Contributor(s):
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 }

Generated on Mon Jan 22 15:16:09 2007 for ProActive by  doxygen 1.5.1