1 package fr.jayasoft.ivy.repository.ssh; 2 3 import java.io.File ; 4 import java.io.IOException ; 5 import java.util.HashMap ; 6 import java.util.Map ; 7 8 import com.jcraft.jsch.ChannelSftp; 9 import com.jcraft.jsch.JSch; 10 import com.jcraft.jsch.JSchException; 11 import com.jcraft.jsch.Session; 12 import com.jcraft.jsch.UserInfo; 13 14 import fr.jayasoft.ivy.IvyContext; 15 import fr.jayasoft.ivy.event.IvyEvent; 16 import fr.jayasoft.ivy.event.IvyListener; 17 import fr.jayasoft.ivy.event.resolve.EndResolveEvent; 18 import fr.jayasoft.ivy.util.Credentials; 19 import fr.jayasoft.ivy.util.CredentialsUtil; 20 import fr.jayasoft.ivy.util.Message; 21 22 29 public class SshCache { 30 31 private SshCache() {}; 32 33 private static SshCache instance = new SshCache(); 34 35 public static SshCache getInstance() { 36 return instance; 37 } 38 39 private class Entry { 40 private Session session = null; 41 private ChannelSftp channelSftp = null; 42 private String host = null; 43 private String user = null; 44 private int port = 22; 45 46 49 public String getHost() { 50 return host; 51 } 52 53 56 public int getPort() { 57 return port; 58 } 59 60 63 public String getUser() { 64 return user; 65 } 66 67 public Entry(Session newSession, String newUser, String newHost, int newPort) { 68 session = newSession; 69 host = newHost; 70 user = newUser; 71 port = newPort; 72 IvyContext.getContext().getIvy().addIvyListener(new IvyListener() { 73 public void progress(IvyEvent event) { 74 event.getSource().removeIvyListener(this); 75 clearSession(session); 76 } 77 }, EndResolveEvent.NAME); 78 } 79 80 84 public void setChannelSftp(ChannelSftp newChannel) { 85 if(channelSftp != null && newChannel != null ) 86 throw new IllegalStateException ("Only one sftp channelSftp per session allowed"); 87 this.channelSftp = newChannel; 88 } 89 90 93 public ChannelSftp getChannelSftp() { 94 return channelSftp; 95 } 96 97 100 private Session getSession() { 101 return session; 102 } 103 104 107 public void releaseChannelSftp() { 108 if(channelSftp != null) { 109 if(channelSftp.isConnected()) { 110 Message.verbose(":: SFTP :: closing sftp connection from "+host+"..."); 111 channelSftp.disconnect(); 112 channelSftp = null; 113 Message.verbose(":: SFTP :: sftp connection closed from "+host); 114 } 115 } 116 } 117 } 118 122 private Map uriCacheMap = new HashMap (); 123 126 private Map sessionCacheMap = new HashMap (); 127 128 133 private Entry getCacheEntry(String user, String host, int port) { 134 return (Entry)uriCacheMap.get(createCacheKey(user, host, port)); 135 } 136 137 144 private static String createCacheKey(String user, String host, int port) { 145 String portToUse = "22"; 146 if(port != -1 && port != 22) 147 portToUse = Integer.toString(port); 148 return user.toLowerCase().trim()+"@"+host.toLowerCase().trim()+":"+portToUse; 149 } 150 151 156 private Entry getCacheEntry(Session session) { 157 return (Entry)sessionCacheMap.get(session); 158 } 159 160 168 private void setSession(String user, String host, int port, Session newSession) { 169 Entry entry = (Entry)uriCacheMap.get(createCacheKey(user, host, port)); 170 Session oldSession = null; 171 if(entry != null) 172 oldSession = entry.getSession(); 173 if(oldSession != null && !oldSession.equals(newSession) && 174 oldSession.isConnected()) { 175 entry.releaseChannelSftp(); 176 String oldhost = oldSession.getHost(); 177 Message.verbose(":: SSH :: closing ssh connection from "+oldhost+"..."); 178 oldSession.disconnect(); 179 Message.verbose(":: SSH :: ssh connection closed from "+oldhost); 180 } 181 if((newSession == null) && (entry != null)) { 182 uriCacheMap.remove(createCacheKey(user, host, port)); 183 if(entry.getSession() != null) 184 sessionCacheMap.remove(entry.getSession()); 185 } else { 186 Entry newEntry = new Entry(newSession,user,host,port); 187 uriCacheMap.put(createCacheKey(user, host, port), newEntry); 188 sessionCacheMap.put(newSession, newEntry); 189 } 190 } 191 192 196 public void clearSession(Session session) { 197 Entry entry = (Entry)sessionCacheMap.get(session); 198 if(entry != null) 199 setSession(entry.getUser(), entry.getHost(), entry.getPort(), null); 200 } 201 202 207 public ChannelSftp getChannelSftp(Session session) throws IOException { 208 ChannelSftp channel = null; 209 Entry entry = getCacheEntry(session); 210 if(entry != null) { 211 channel = entry.getChannelSftp(); 212 if(channel != null && !channel.isConnected()) { 213 entry.releaseChannelSftp(); 214 channel = null; 215 } 216 } 217 return channel; 218 } 219 220 225 public void attachChannelSftp(Session session, ChannelSftp channel) { 226 Entry entry = getCacheEntry(session); 227 if(entry == null) 228 throw new IllegalArgumentException ("No entry for "+session+" in the cache"); 229 entry.setChannelSftp(channel); 230 } 231 232 243 public Session getSession(String host, 244 int port, 245 String username, 246 String userPassword, 247 File pemFile, 248 String pemPassword, 249 File passFile) throws IOException { 250 Entry entry = getCacheEntry(username, host, port); 251 Session session = null; 252 if(entry != null) 253 session = entry.getSession(); 254 if(session == null || !session.isConnected()) { 255 Message.verbose(":: SSH :: connecting to "+host+"..."); 256 try { 257 JSch jsch=new JSch(); 258 if(port != -1) 259 session = jsch.getSession(username,host,port); 260 else 261 session = jsch.getSession(username,host); 262 if(pemFile != null) { 263 jsch.addIdentity(pemFile.getAbsolutePath(), pemPassword); 264 } 265 session.setUserInfo(new cfUserInfo(host,username,userPassword,pemFile,pemPassword,passFile)); 266 session.connect(); 267 Message.verbose(":: SSH :: connected to "+host+"!"); 268 setSession(username, host, port, session); 269 } catch (JSchException e) { 270 if (passFile.exists()) { 271 passFile.delete(); 272 } 273 IOException ex = new IOException (e.getMessage()); 274 ex.initCause(e); 275 throw ex; 276 } 277 } 278 return session; 279 } 280 281 284 private static class cfUserInfo implements UserInfo { 285 286 private String userPassword; 287 private String pemPassword; 288 private String userName; 289 private final File pemFile; 290 private final String host; 291 private final File passfile; 292 293 public cfUserInfo(String host, String userName, String userPassword, File pemFile, String pemPassword, File passfile) { 294 this.userPassword = userPassword; 295 this.pemPassword = pemPassword; 296 this.host = host; 297 this.passfile = passfile; 298 this.userName = userName; 299 this.pemFile = pemFile; 300 } 301 302 public void showMessage(String message) { 303 Message.info(message); 304 } 305 306 public boolean promptYesNo(String message) { 307 return true; 308 } 309 310 public boolean promptPassword(String message) { 311 return true; 312 } 313 314 public boolean promptPassphrase(String message) { 315 return true; 316 } 317 318 public String getPassword() { 319 if(userPassword == null) { 320 Credentials c = CredentialsUtil.promptCredentials(new Credentials(null, host, userName, userPassword), passfile); 321 if (c != null) { 322 userName = c.getUserName(); 323 userPassword = c.getPasswd(); 324 } 325 } 326 return userPassword; 327 } 328 329 public String getPassphrase() { 330 if(pemPassword == null && pemFile != null) { 331 Credentials c = CredentialsUtil.promptCredentials(new Credentials(null, pemFile.getAbsolutePath(), userName, pemPassword), passfile); 332 if (c != null) { 333 userName = c.getUserName(); 334 pemPassword = c.getPasswd(); 335 } 336 } 337 return pemPassword; 338 } 339 } 340 } 341 | Popular Tags |