1 12 package org.eclipse.team.internal.ccvs.ssh2; 13 import java.io.*; 14 import java.net.NoRouteToHostException ; 15 import java.net.UnknownHostException ; 16 17 import org.eclipse.core.runtime.IProgressMonitor; 18 import org.eclipse.osgi.util.NLS; 19 import org.eclipse.team.internal.ccvs.core.ICVSRepositoryLocation; 20 import org.eclipse.team.internal.ccvs.core.IServerConnection; 21 import org.eclipse.team.internal.ccvs.core.connection.CVSAuthenticationException; 22 import org.eclipse.team.internal.ccvs.ssh.SSHServerConnection; 23 import org.eclipse.team.internal.core.streams.*; 24 25 import com.jcraft.jsch.*; 26 27 31 public class CVSSSH2ServerConnection implements IServerConnection { 32 private final class SSH2IOException extends IOException { 33 private static final long serialVersionUID = 1L; 34 35 private final JSchException e; 36 37 SSH2IOException(String s, JSchException e) { 38 super(s); 39 this.e = e; 40 } 41 42 public Throwable getCause() { 43 return e; 44 } 45 } 46 private static final String COMMAND = "cvs server"; private ICVSRepositoryLocation location; 48 private String password; 49 private InputStream inputStream; 50 private OutputStream outputStream; 51 private JSchSession session; 52 private Channel channel; 53 private IServerConnection ssh1; 54 55 protected CVSSSH2ServerConnection(ICVSRepositoryLocation location, String password) { 56 this.location = location; 57 this.password = password; 58 } 59 public void close() throws IOException { 60 if (ssh1 != null) { 61 ssh1.close(); 62 ssh1 = null; 63 return; 64 } 65 try { 66 if (inputStream != null) { 67 try { 68 inputStream.close(); 69 } catch (IOException e) { 70 } 72 } 73 } finally { 74 try { 75 if (outputStream != null) { 76 try { 77 outputStream.close(); 78 } catch (IOException e) { 79 } 81 } 82 } finally { 83 if (channel != null) 84 channel.disconnect(); 85 } 86 } 87 } 88 public InputStream getInputStream() { 89 if (ssh1 != null) { 90 return ssh1.getInputStream(); 91 } 92 return inputStream; 93 } 94 public OutputStream getOutputStream() { 95 if (ssh1 != null) { 96 return ssh1.getOutputStream(); 97 } 98 return outputStream; 99 } 100 public void open(IProgressMonitor monitor) throws IOException, CVSAuthenticationException { 101 if (ssh1 != null) { 102 ssh1.open(monitor); 103 return; 104 } 105 monitor.subTask(NLS.bind(CVSSSH2Messages.CVSSSH2ServerConnection_open, new String [] { location.getHost() })); 106 monitor.worked(1); 107 internalOpen(monitor); 108 } 109 114 private void internalOpen(IProgressMonitor monitor) throws IOException, CVSAuthenticationException { 115 try { 116 OutputStream channel_out = null; 117 InputStream channel_in = null; 118 boolean firstTime = true; 119 boolean tryAgain = false; 120 while (firstTime || tryAgain) { 121 tryAgain = false; session = JSchSession.getSession(location, location.getUsername(), password, location.getHost(), location.getPort(), monitor); 123 channel = session.getSession().openChannel("exec"); ((ChannelExec) channel).setCommand(COMMAND); 125 channel_out = channel.getOutputStream(); 126 channel_in = channel.getInputStream(); 127 try { 128 channel.connect(); 129 } catch (JSchException ee) { 130 try { 136 if (firstTime && (isSessionDownError(ee) || isChannelNotOpenError(ee))) { 137 tryAgain = true; 138 } 139 if (!tryAgain) { 140 throw ee; 141 } 142 } finally { 143 session.dispose(); 145 } 146 } 147 firstTime = false; } 149 int timeout = location.getTimeout(); 150 inputStream = new PollingInputStream(new TimeoutInputStream(new FilterInputStream(channel_in) { 151 public void close() { 152 } 154 }, 155 8192 , 1000 , -1 , true ), timeout > 0 ? timeout : 1, monitor); 156 outputStream = new PollingOutputStream(new TimeoutOutputStream(new FilterOutputStream(channel_out) { 157 public void close() { 158 } 160 }, 161 8192 , 1000 , 1000 ), timeout > 0 ? timeout : 1, monitor); 162 } catch (final JSchException e) { 163 if (isSSH2Unsupported(e)) { 164 ssh1 = new SSHServerConnection(location, password); 165 if (ssh1 == null) { 166 throw new SSH2IOException(e.toString(), e); 167 } 168 ssh1.open(monitor); 169 } else { 170 String message = e.getMessage(); 171 if (JSchSession.isAuthenticationFailure(e)) { 172 throw new CVSAuthenticationException(CVSSSH2Messages.CVSSSH2ServerConnection_0, CVSAuthenticationException.NO_RETRY,location, e); 174 } else if (message.startsWith("Session.connect: ")) { int start = message.indexOf(": ") + 1; if (start != -1) { 179 int end = message.indexOf(": ", start); if (end != -1) { 181 String exception = message.substring(start, end).trim(); 182 if (exception.indexOf("NoRouteToHostException") != -1) { message = NLS.bind(CVSSSH2Messages.CVSSSH2ServerConnection_1, new String [] { location.getHost() }); 184 throw new NoRouteToHostException (message); 185 } else if (exception.indexOf("java.net.UnknownHostException") != -1) { throw new UnknownHostException (location.getHost()); 187 } else { 188 message = message.substring(end + 1).trim(); 189 } 190 } 191 } 192 } 193 throw new SSH2IOException(message, e); 194 } 195 } 196 } 197 198 private boolean isChannelNotOpenError(JSchException ee) { 199 return ee.getMessage().indexOf("channel is not opened") != -1; } 201 private boolean isSessionDownError(JSchException ee) { 202 return ee.getMessage().equals("session is down"); } 204 private boolean isSSH2Unsupported(JSchException e) { 205 return e.toString().indexOf("invalid server's version string") != -1; } 207 } 208 | Popular Tags |