1 11 package org.eclipse.team.internal.ccvs.core.connection; 12 13 import java.io.*; 14 import java.net.Socket ; 15 16 import org.eclipse.core.net.proxy.IProxyData; 17 import org.eclipse.core.runtime.IProgressMonitor; 18 import org.eclipse.jsch.core.IJSchService; 19 import org.eclipse.osgi.util.NLS; 20 import org.eclipse.team.internal.ccvs.core.*; 21 import org.eclipse.team.internal.ccvs.core.util.Util; 22 import org.eclipse.team.internal.core.streams.*; 23 24 import com.jcraft.jsch.Proxy; 25 26 29 public class PServerConnection implements IServerConnection { 30 31 public static final char NEWLINE= 0xA; 32 33 34 private static final int DEFAULT_PORT= 2401; 35 36 37 private static final char ERROR_CHAR = 'E'; 38 private static final String ERROR_MESSAGE = "error 0"; private static final String NO_SUCH_USER = "no such user"; 41 private static final char[] SCRAMBLING_TABLE=new char[] { 42 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15, 43 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 44 114,120,53,79,96,109,72,108,70,64,76,67,116,74,68,87, 45 111,52,75,119,49,34,82,81,95,65,112,86,118,110,122,105, 46 41,57,83,43,46,102,40,89,38,103,45,50,42,123,91,35, 47 125,55,54,66,124,126,59,47,92,71,115,78,88,107,106,56, 48 36,121,117,104,101,100,69,73,99,63,94,93,39,37,61,48, 49 58,113,32,90,44,98,60,51,33,97,62,77,84,80,85,223, 50 225,216,187,166,229,189,222,188,141,249,148,200,184,136,248,190, 51 199,170,181,204,138,232,218,183,255,234,220,247,213,203,226,193, 52 174,172,228,252,217,201,131,230,197,211,145,238,161,179,160,212, 53 207,221,254,173,202,146,224,151,140,196,205,130,135,133,143,246, 54 192,159,244,239,185,168,215,144,139,165,180,157,147,186,214,176, 55 227,231,219,169,175,156,206,198,129,164,150,210,154,177,134,127, 56 182,128,158,208,162,132,167,209,149,241,153,251,237,236,171,195, 57 243,233,253,240,194,250,191,155,142,137,245,235,163,242,178,152 58 }; 59 60 61 private static final String BEGIN= "BEGIN AUTH REQUEST"; private static final String END= "END AUTH REQUEST"; private static final String LOGIN_OK= "I LOVE YOU"; private static final String LOGIN_FAILED= "I HATE YOU"; 66 private String password; 67 private ICVSRepositoryLocation cvsroot; 68 69 private Socket fSocket; 70 71 private InputStream inputStream; 72 private OutputStream outputStream; 73 74 77 public void close() throws IOException { 78 try { 79 if (inputStream != null) inputStream.close(); 80 } finally { 81 inputStream = null; 82 try { 83 if (outputStream != null) outputStream.close(); 84 } finally { 85 outputStream = null; 86 try { 87 if (fSocket != null) fSocket.close(); 88 } finally { 89 fSocket = null; 90 } 91 } 92 } 93 } 94 95 98 public void open(IProgressMonitor monitor) throws IOException, CVSAuthenticationException { 99 100 monitor.subTask(CVSMessages.PServerConnection_authenticating); 101 monitor.worked(1); 102 103 InputStream is = null; 104 OutputStream os = null; 105 106 Proxy proxy = getProxy(); 107 if (proxy!=null) { 108 String host = cvsroot.getHost(); 109 int port = cvsroot.getPort(); 110 if (port == ICVSRepositoryLocation.USE_DEFAULT_PORT) { 111 port = DEFAULT_PORT; 112 } 113 try { 114 int timeout = CVSProviderPlugin.getPlugin().getTimeout() * 1000; 115 IJSchService service = CVSProviderPlugin.getPlugin().getJSchService(); 116 service.connect(proxy, host, port, timeout, monitor); 117 } catch( Exception ex) { 118 ex.printStackTrace(); 119 throw new IOException(ex.getMessage()); 120 } 121 is = proxy.getInputStream(); 122 os = proxy.getOutputStream(); 123 124 } else { 125 fSocket = createSocket(monitor); 126 is = fSocket.getInputStream(); 127 os = fSocket.getOutputStream(); 128 } 129 130 boolean connected = false; 131 try { 132 this.inputStream = new BufferedInputStream(new PollingInputStream(is, 133 cvsroot.getTimeout(), monitor)); 134 this.outputStream = new PollingOutputStream(new TimeoutOutputStream( 135 os, 8192 , 1000 , 1000 ), 136 cvsroot.getTimeout(), monitor); 137 authenticate(); 138 connected = true; 139 } finally { 140 if (! connected) cleanUpAfterFailedConnection(); 141 } 142 } 143 144 private Proxy getProxy() { 145 IJSchService service = CVSProviderPlugin.getPlugin().getJSchService(); 146 if (service == null) 147 return null; 148 Proxy proxy = service.getProxyForHost(cvsroot.getHost(), IProxyData.SOCKS_PROXY_TYPE); 149 if (proxy == null) 150 proxy = service.getProxyForHost(cvsroot.getHost(), IProxyData.HTTPS_PROXY_TYPE); 151 return proxy; 152 } 153 154 157 public InputStream getInputStream() { 158 return inputStream; 159 } 160 163 public OutputStream getOutputStream() { 164 return outputStream; 165 } 166 167 171 PServerConnection(ICVSRepositoryLocation cvsroot, String password) { 172 this.cvsroot = cvsroot; 173 this.password = password; 174 } 175 178 private void authenticate() throws IOException, CVSAuthenticationException { 179 String scrambledPassword = scramblePassword(password); 180 181 String user = cvsroot.getUsername(); 182 OutputStream out = getOutputStream(); 183 184 StringBuffer request = new StringBuffer (); 185 request.append(BEGIN); 186 request.append(NEWLINE); 187 request.append(cvsroot.getRootDirectory()); 188 request.append(NEWLINE); 189 request.append(user); 190 request.append(NEWLINE); 191 request.append(scrambledPassword); 192 request.append(NEWLINE); 193 request.append(END); 194 request.append(NEWLINE); 195 out.write(request.toString().getBytes()); 196 out.flush(); 197 String line = Connection.readLine(cvsroot, getInputStream()).trim(); 198 199 if (LOGIN_OK.equals(line)) 201 return; 202 203 if (line.length() == 0) { 205 throw new IOException(CVSMessages.PServerConnection_noResponse); 206 } 207 208 String message = ""; String separator = ""; 212 if(!CVSProviderPlugin.getPlugin().isUseProxy()) { 213 while (line.length() > 0 && line.charAt(0) == ERROR_CHAR) { 214 if (line.length() > 2) { 215 message += separator + line.substring(2); 216 separator = " "; } 218 line = Connection.readLine(cvsroot, getInputStream()); 219 } 220 } else { 221 while (line.length() > 0) { 222 message += separator + line; 223 separator = "\n"; line = Connection.readLine(cvsroot, getInputStream()); 225 } 226 } 227 228 if (LOGIN_FAILED.equals(line)) { 230 if (message.length() == 0) { 231 throw new CVSAuthenticationException(CVSMessages.PServerConnection_loginRefused, CVSAuthenticationException.RETRY,cvsroot); 232 } else { 233 throw new CVSAuthenticationException(message, CVSAuthenticationException.RETRY,cvsroot); 234 } 235 } 236 237 if (line.startsWith(ERROR_MESSAGE)) 239 message += separator + line.substring(ERROR_MESSAGE.length() + 1); 240 else 241 message += separator + line; 242 if (message.indexOf(NO_SUCH_USER) != -1) 243 throw new CVSAuthenticationException(NLS.bind(CVSMessages.PServerConnection_invalidUser, (new Object [] {message})), CVSAuthenticationException.RETRY,cvsroot); 244 throw new IOException(NLS.bind(CVSMessages.PServerConnection_connectionRefused, (new Object [] { message }))); 245 } 246 250 private void cleanUpAfterFailedConnection() throws IOException { 251 try { 252 if (inputStream != null) 253 inputStream.close(); 254 } finally { 255 try { 256 if (outputStream != null) 257 outputStream.close(); 258 } finally { 259 try { 260 if (fSocket != null) 261 fSocket.close(); 262 } finally { 263 fSocket = null; 264 } 265 } 266 } 267 268 } 269 272 protected Socket createSocket(IProgressMonitor monitor) throws IOException { 273 int port = cvsroot.getPort(); 275 if (port == ICVSRepositoryLocation.USE_DEFAULT_PORT) 276 port = DEFAULT_PORT; 277 Socket result; 279 try { 280 result= Util.createSocket(cvsroot.getHost(), port, monitor); 281 result.setTcpNoDelay(true); 283 } catch (InterruptedIOException e) { 284 throw new InterruptedIOException(NLS.bind(CVSMessages.PServerConnection_socket, (new Object [] {cvsroot.getHost()}))); 286 } 287 result.setSoTimeout(1000); return result; 289 } 290 291 private String scramblePassword(String password) throws CVSAuthenticationException { 292 int length = password.length(); 293 char[] out= new char[length]; 294 for (int i= 0; i < length; i++) { 295 char value = password.charAt(i); 296 if( value < 0 || value > 255 ) 297 throwInValidCharacter(); 298 out[i]= SCRAMBLING_TABLE[value]; 299 } 300 return "A" + new String (out); } 302 303 private void throwInValidCharacter() throws CVSAuthenticationException { 304 throw new CVSAuthenticationException(CVSMessages.PServerConnection_invalidChars, CVSAuthenticationException.RETRY, cvsroot); 305 } 306 307 } 308 | Popular Tags |