Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 195644 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/tptp/platform/execution/util/internal/Constants.java (+7 lines)
Lines 103-108 Link Here
103
	public static final long CONNECT_DATA              	=0x10000000;
103
	public static final long CONNECT_DATA              	=0x10000000;
104
	public static final long DATA_CONNECTION_COMPLETE  	=0x20000000;
104
	public static final long DATA_CONNECTION_COMPLETE  	=0x20000000;
105
	public static final long DATA_CONNECTION_REFUSED   	=0x40000000;
105
	public static final long DATA_CONNECTION_REFUSED   	=0x40000000;
106
	
107
	public static final long SECURITY_REQUIRED   		=0x00010000;
108
	public static final long AUTHENTICATE   			=0x00020000;
109
	public static final long AUTHENTICATION_FAILED   	=0x00040000;
110
	public static final long AUTHENTICATION_SUCCESSFUL  =0x00080000;
111
	
106
	public static final long DATA_PATH_SEND				=0x00000001;
112
	public static final long DATA_PATH_SEND				=0x00000001;
107
	public static final long DATA_PATH_RECEIVE 			=0x00000002;
113
	public static final long DATA_PATH_RECEIVE 			=0x00000002;
108
	public static final long DATA_PATH_TWO_WAY 			= DATA_PATH_SEND | DATA_PATH_RECEIVE;
114
	public static final long DATA_PATH_TWO_WAY 			= DATA_PATH_SEND | DATA_PATH_RECEIVE;
Lines 204-209 Link Here
204
	public static final int PROCESS_LAUNCH_TIMEOUT_TRY_COUNT	= 50;
210
	public static final int PROCESS_LAUNCH_TIMEOUT_TRY_COUNT	= 50;
205
	public static final int DSSRVR_LAUNCH_TIMEOUT_TRY_COUNT		= 1000;
211
	public static final int DSSRVR_LAUNCH_TIMEOUT_TRY_COUNT		= 1000;
206
	public static final int CONNECT_TIMEOUT_TRY_COUNT = 32;
212
	public static final int CONNECT_TIMEOUT_TRY_COUNT = 32;
213
	public static final int WAIT_RESPONCE_TIMEOUT = 10000;
207
	
214
	
208
	public static final boolean TPTP_AC					= true;
215
	public static final boolean TPTP_AC					= true;
209
216
(-)src/org/eclipse/tptp/platform/execution/util/internal/AgentControllerPool.java (-44 / +80 lines)
Lines 18-24 Link Here
18
import org.eclipse.tptp.platform.execution.client.core.INode;
18
import org.eclipse.tptp.platform.execution.client.core.INode;
19
import org.eclipse.tptp.platform.execution.client.core.NodeFactory;
19
import org.eclipse.tptp.platform.execution.client.core.NodeFactory;
20
import org.eclipse.tptp.platform.execution.exceptions.AgentControllerUnavailableException;
20
import org.eclipse.tptp.platform.execution.exceptions.AgentControllerUnavailableException;
21
import org.eclipse.tptp.platform.execution.exceptions.LoginFailedException;
21
import org.eclipse.tptp.platform.execution.exceptions.NotConnectedException;
22
import org.eclipse.tptp.platform.execution.exceptions.NotConnectedException;
23
import org.eclipse.tptp.platform.execution.exceptions.SecureConnectionRequiredException;
24
import org.eclipse.tptp.platform.execution.security.User;
22
25
23
/**
26
/**
24
 * This delegate is used to keep track of connections with Agent Controller.
27
 * This delegate is used to keep track of connections with Agent Controller.
Lines 28-34 Link Here
28
 * 
31
 * 
29
 * @author Ali Mehregani
32
 * @author Ali Mehregani
30
 */
33
 */
31
public class AgentControllerPool {
34
public class AgentControllerPool {	// may be inherited to provide UI
32
	/**
35
	/**
33
	 * The incremental wait times
36
	 * The incremental wait times
34
	 */
37
	 */
Lines 40-46 Link Here
40
	public static final int TOTAL_WAIT = 100;
43
	public static final int TOTAL_WAIT = 100;
41
44
42
	/* The instance of this class */
45
	/* The instance of this class */
43
	private static AgentControllerPool instance = new AgentControllerPool();
46
	protected static AgentControllerPool instance;
44
47
45
	/*
48
	/*
46
	 * Keeps track of the connections to Agent Controller KEY = hostname VALUE =
49
	 * Keeps track of the connections to Agent Controller KEY = hostname VALUE =
Lines 60-74 Link Here
60
	/**
63
	/**
61
	 * Hide the construtor
64
	 * Hide the construtor
62
	 */
65
	 */
63
	private AgentControllerPool() {
66
	protected AgentControllerPool() {
64
	}
67
	}
65
68
66
	/**
69
	/**
67
	 * Return the instance of this singleton class
70
	 * Return the instance of this singleton class 
68
	 * 
71
	 * 
69
	 * @return The instance of this class
72
	 * @return The instance of this class
70
	 */
73
	 */
71
	public static AgentControllerPool getInstance() {
74
	public static AgentControllerPool getInstance() {
75
		if (instance == null) instance = new AgentControllerPool();
72
		return instance;
76
		return instance;
73
	}
77
	}
74
78
Lines 93-100 Link Here
93
	 */
97
	 */
94
	public IAgentController getConnection(String hostName, int portNumber,
98
	public IAgentController getConnection(String hostName, int portNumber,
95
			boolean reuseExistingConnection) throws Exception {
99
			boolean reuseExistingConnection) throws Exception {
100
		
96
		String hostKeyName = AgentStatePool.getUnifiedHostName(hostName);
101
		String hostKeyName = AgentStatePool.getUnifiedHostName(hostName);
97
98
		/* Attempt to lookup the connection */
102
		/* Attempt to lookup the connection */
99
		IAgentController ac = (IAgentController) connectionPool.get(hostKeyName);
103
		IAgentController ac = (IAgentController) connectionPool.get(hostKeyName);
100
104
Lines 155-188 Link Here
155
		class EstablishConnection implements Runnable {
159
		class EstablishConnection implements Runnable {
156
			private Exception e;
160
			private Exception e;
157
			private IAgentController ac;
161
			private IAgentController ac;
162
			private User user;
158
163
159
			public void run() {
164
			public void run() {
160
				try {
165
				try {
161
					ac = node.connect(connInfo);
166
					if (user == null)
167
						ac = node.connect(connInfo);
168
					else
169
						ac = node.connect(connInfo, user);
162
170
163
					/* Notify that the connection is done */
171
					/* Notify that the connection is done */
164
					synchronized (AgentControllerPool.this) {
172
				} catch (LoginFailedException e) {
165
						AgentControllerPool.this.notify();
173
				} catch (SecureConnectionRequiredException e) {
166
					}
167
				} catch (Exception e) {
174
				} catch (Exception e) {
168
					/*
175
					/*
169
					 * For some reason Sun JDK 1.5_06 has problems resolving the
176
					 * For some reason Sun JDK 1.5_06 has problems resolving the
170
					 * hostname "localhost". As a workaround change it to
177
					 * hostname "localhost". As a workaround change it to
171
					 * 127.0.0.1
178
					 * 127.0.0.1
172
					 */
179
					 */
180
181
					this.e = e;
182
					
173
					if ("localhost".equals(connInfo.getHostName())) {
183
					if ("localhost".equals(connInfo.getHostName())) {
174
						connInfo.setHostName("127.0.0.1");
184
						connInfo.setHostName("127.0.0.1");
185
					
186
						try {
187
							ac = node.connect(connInfo);
188
							this.e = null;
189
						} catch (Exception ex) {}
175
					}
190
					}
176
					try {
177
						ac = node.connect(connInfo);
178
179
						/* Notify that the connection is done */
180
						synchronized (AgentControllerPool.this) {
181
							AgentControllerPool.this.notify();
182
						}
183
					} catch (Exception ex) {
184
					}
185
					this.e = e;
186
				}
191
				}
187
			}
192
			}
188
193
Lines 193-234 Link Here
193
			public IAgentController getConnection() {
198
			public IAgentController getConnection() {
194
				return ac;
199
				return ac;
195
			}
200
			}
201
			
202
			public void setUser(User user) {
203
				this.user = user;
204
			}
196
		}
205
		}
197
		;
198
206
199
		EstablishConnection establishConnection = new EstablishConnection();
207
		EstablishConnection establishConnection = new EstablishConnection();
200
		int totalWait = 0;
208
		boolean connected = false;
201
		new Thread(establishConnection).start();
209
		String userName = null;
202
210
		boolean lookingForUser = true;
203
		/* Wait for a maximum of 10 seconds before bailing out */
211
		int retry = 0;
204
		while (establishConnection.getConnection() == null
212
		
205
				&& totalWait < TOTAL_WAIT
213
		do {
206
				&& establishConnection.getException() == null) {
214
			Thread ect = new Thread(establishConnection);
207
			totalWait++;
215
			ect.start();
208
			synchronized (this) {
216
			/* Wait for a maximum of 10 seconds before bailing out */
209
				try {
217
			ect.join(TOTAL_WAIT*INCREMENTAL_WAIT);
210
					wait(INCREMENTAL_WAIT);
218
			if (ect.isAlive()) ect.interrupt();
211
				} catch (InterruptedException e) {
219
			
212
					/* Bail out */
220
			Exception error = establishConnection.getException();
213
					break;
221
			if (error != null) throw error;
222
			
223
			ac = establishConnection.getConnection();
224
			if (ac == null) {
225
				throw new AgentControllerUnavailableException("");
226
			}
227
			
228
			if (ac.isAuthenticated()) break;
229
			
230
			User user = null;
231
			if (lookingForUser) {
232
				user = findUser(hostName);
233
				lookingForUser = false;
234
				if (user != null) {
235
					userName = user.getName();
236
					establishConnection.setUser(user);
237
					continue;		// try it
214
				}
238
				}
215
			}
239
			}
240
			
241
			user = promptAuthentication(hostName, userName);
242
			if(user == null) break;
243
244
			userName = user.getName();
245
			establishConnection.setUser(user);
246
		} while (retry++ < 3);
247
248
		if (!ac.isAuthenticated()) {
249
			try { ac.disconnect(); } catch (Exception e) {}
250
			throw new LoginFailedException("Authentication failed");
216
		}
251
		}
217
252
		
218
		/* If any errors occurred, then return it */
219
		Exception error = establishConnection.getException();
220
		if (error != null)
221
			throw error;
222
		ac = establishConnection.getConnection();
223
		if (ac == null)
224
			throw new AgentControllerUnavailableException();
225
226
		/* Store and return the connection */
253
		/* Store and return the connection */
227
		connectionPool.put(hostKeyName, ac);
254
		connectionPool.put(hostKeyName, ac);
228
		setPortMapping(hostKeyName, portNumber, ac.getConnectionInfo().getPort());
255
		setPortMapping(hostKeyName, portNumber, ac.getConnectionInfo().getPort());
229
		return ac;
256
		return ac;
230
	}
257
	}
231
258
	
232
	private int getPortMapping(String host, int port) {
259
	private int getPortMapping(String host, int port) {
233
		String key = host + ":" + port;
260
		String key = host + ":" + port;
234
		if (portMappings.containsKey(key)) {
261
		if (portMappings.containsKey(key)) {
Lines 242-245 Link Here
242
		String key = host + ":" + port;
269
		String key = host + ":" + port;
243
		portMappings.put(key, new Integer(newPort));
270
		portMappings.put(key, new Integer(newPort));
244
	}
271
	}
272
273
	// 	to prevent multiple User registration, to be substituted by descendants
274
	public User findUser(String hostName) {
275
		return null;
276
	}
277
					
278
	public User promptAuthentication(String hostName, String userName) {
279
		return null;
280
	}
245
}
281
}
(-)src/org/eclipse/tptp/platform/execution/client/core/internal/SecureConnectionImpl.java (-132 / +81 lines)
Lines 1-145 Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2005, 2006 IBM Corporation, Intel Corporation.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *    IBM Corporation - Initial API and implementation
10
 *    Vishnu K Naikawadi, Intel - Initial API and implementation
11
 *
12
 * $Id$ 
13
 *******************************************************************************/
14
15
package org.eclipse.tptp.platform.execution.client.core.internal;
1
package org.eclipse.tptp.platform.execution.client.core.internal;
16
2
17
18
import java.io.IOException;
3
import java.io.IOException;
19
import java.net.ConnectException;
4
import java.net.Socket;
20
import java.net.InetAddress;
21
import java.security.KeyManagementException;
22
import java.security.NoSuchAlgorithmException;
23
import java.security.Security;
24
25
import javax.net.ssl.HandshakeCompletedEvent;
26
import javax.net.ssl.HandshakeCompletedListener;
27
import javax.net.ssl.SSLSession;
28
import javax.net.ssl.SSLSocket;
29
import javax.net.ssl.SSLSocketFactory;
30
31
import org.eclipse.tptp.platform.execution.client.core.*;
32
import org.eclipse.tptp.platform.execution.security.*;
33
import org.eclipse.tptp.platform.execution.exceptions.*;
34
import org.eclipse.tptp.platform.execution.util.internal.*;
35
36
5
37
import javax.net.ssl.SSLContext;
6
import javax.net.ssl.SSLContext;
7
import javax.net.ssl.SSLSocket;
8
import javax.net.ssl.TrustManager;
9
10
import org.eclipse.tptp.platform.execution.client.core.INode;
11
import org.eclipse.tptp.platform.execution.exceptions.LoginFailedException;
12
import org.eclipse.tptp.platform.execution.exceptions.ReconnectRequestedException;
13
import org.eclipse.tptp.platform.execution.exceptions.SecureConnectionRequiredException;
14
import org.eclipse.tptp.platform.execution.exceptions.UntrustedAgentControllerException;
38
15
39
public class SecureConnectionImpl extends ConnectionImpl {
16
public class SecureConnectionImpl extends ConnectionImpl {
40
	
17
    private SSLSocket initSSL (Socket socket) throws IOException {
41
	private boolean handshakeSuccess;
18
    	if (socket == null || !socket.isConnected()) return null;
19
    	
20
		TrustManager tms[] = null;
21
		try {
22
			X509TrustManagerImpl tm = new X509TrustManagerImpl();
23
			tms = new TrustManager[1];
24
			tms[0] = tm;
25
		} catch (Exception e) {}
26
		
27
		SSLContext sslCtx;
28
		try {
29
			sslCtx = SSLContext.getInstance("SSL");
30
			sslCtx.init(null, tms, null);
31
		}
32
		catch(Exception e) {
33
			sslCtx = null;
34
		}
35
		
36
		if (sslCtx == null) return null;
37
		
38
		String host = socket.getInetAddress().getHostAddress();
39
		int port = socket.getPort();
40
		
41
		SSLSocket sslSocket = (SSLSocket) sslCtx.getSocketFactory().createSocket(socket, host, port, true);
42
		sslSocket.setUseClientMode(true);
42
43
43
    public SecureConnectionImpl() {
44
		sslSocket.startHandshake();
44
        super();
45
    }
46
45
47
    public void connect(INode node, SecureConnectionInfo connInfo) throws IOException, SecureConnectionRequiredException, LoginFailedException, UntrustedAgentControllerException, ReconnectRequestedException {
46
		if (sslSocket.getSession() == null) return null;
48
        _port = connInfo.getPort();
49
        int offset = 0;
50
        InetAddress[] addrs = node.getAllInetAddresses();
51
        int protocolOffset = 0;
52
        ISecureClientParameters ClientSecureParams = connInfo.getSecureClientParameters();
53
        
54
        /* Determine our acceptable protocols */
55
		String[] sslProtocols = ClientSecureParams.getEnabledProtocols();
56
		if(sslProtocols==null) {
57
			sslProtocols=new String[] {"SSL"};
58
		}
59
		
47
		
60
        do {
48
		return sslSocket;
61
            /* Connect to the remote machine */
62
            try {
63
                /* Attach using SSL and initiate a handshake */
64
                SSLContext sslContext = SSLContext.getInstance(sslProtocols[protocolOffset]/*,node.getSecurityParameters().getSecurityProvider()*/);
65
                //Commented the line below to support security for the RAC since it is not part of the new API
66
                //sslContext.init(ClientSecureParams.getKeystoreManager().getKeyManagers(), node.getAgentController(_port).getSecurityParameters().getKeystoreManager().getTrustManagers(), null);
67
68
                if (sslContext == null) {
69
                    Security.addProvider(ClientSecureParams.getSecurityProvider());
70
71
                    _socket = SSLSocketFactory.getDefault().createSocket(addrs[offset], _port);
72
                    ((SSLSocket) _socket).addHandshakeCompletedListener(new HandshakeCompletedListener() {
73
                        public void handshakeCompleted(HandshakeCompletedEvent e) {	
74
                        }
75
                    });
76
77
                    ((SSLSocket) _socket).startHandshake();
78
                }
79
                else {
80
                    _socket = sslContext.getSocketFactory().createSocket(addrs[offset], _port);
81
                    ((SSLSocket) _socket).addHandshakeCompletedListener(new HandshakeCompletedListener() {
82
                        public void handshakeCompleted(HandshakeCompletedEvent e) {	
83
                        }
84
                    });
85
                }
86
                
87
				String[] cyphers=ClientSecureParams.getEnabledCipherSuites();
88
				if(cyphers!=null) {
89
					((SSLSocket) _socket).setEnabledCipherSuites(ClientSecureParams.getEnabledCipherSuites());
90
				}
91
				else {
92
					((SSLSocket) _socket).setEnabledCipherSuites(((SSLSocket)_socket).getSupportedCipherSuites());
93
				}
94
				((SSLSocket) _socket).setUseClientMode(true);
95
                
96
				//((SSLSocket) _socket).startHandshake();
97
98
                /* The underlying JSSE code returns the SSL socket before all
99
                 * the SSL handshakes, including client authentication, are
100
                 * completed.  The handshake carries on, asynchronously, in
101
                 * the background. If the handshake fails then the socket is
102
                 * not usable. We synchronize things by calling getSession()
103
                 * on the SSL socket.  The thread calling getSession() is
104
                 * forced to wait until the underlying SSL handshake is completed,
105
                 *  and if the handshake fails then getSession() returns a null.
106
                 */
107
                SSLSession session = ((SSLSocket) _socket).getSession();
108
109
                /* If we could not establish a session we should throw an exception */
110
                if (session==null) {
111
                    throw new UntrustedAgentControllerException(Constants.TPTP_PLATFORM_EXEC_MSG39);
112
                }
113
                if(session.getCipherSuite().equals("SSL_NULL_WITH_NULL_NULL")) {
114
					throw new UntrustedAgentControllerException(Constants.TPTP_PLATFORM_EXEC_MSG39);
115
                }
116
				break;
117
            }
118
            catch (ConnectException e) {
119
                offset++;
120
                if (offset == addrs.length) {
121
                    throw e;
122
                }
123
                /* Reset protocol offset */
124
                protocolOffset = 0;
125
            }
126
            catch (NoSuchAlgorithmException e) {
127
                /* Try another protocol if there are any left */
128
                protocolOffset++;
129
                if (protocolOffset == sslProtocols.length) {
130
                    throw new ConnectException(Constants.TPTP_PLATFORM_EXEC_MSG40);
131
                }
132
            }
133
            //Commented the exception block below to allow for security - not implemented in the AC 
134
//            catch (KeyManagementException e) {
135
//                /* We need to handle this */
136
//            }
137
        }
138
        while (offset < addrs.length);
139
140
        sendConnectCommand();
141
        _node = node;
142
        this.init();
143
    }
49
    }
50
    
51
    public boolean connect(INode node, ConnectionImpl con) throws IOException, UntrustedAgentControllerException, 
52
    	ReconnectRequestedException, SecureConnectionRequiredException, LoginFailedException {
53
54
    	if (con == null) return false;
55
    	Socket socket = con.getSocket();
56
    	if (socket == null || !socket.isConnected()) return false;
57
    	
58
    	con.setSocket(null);	// to save socket from garbage collecting
59
    	
60
		setSoTimeout(socket.getSoTimeout());
61
		_node = node;
62
		_port = socket.getPort();
63
		inetAddress = socket.getInetAddress();
64
			
65
		SSLSocket sslSocket = initSSL(socket);
66
		if (sslSocket == null) return false;
67
		
68
		setSocket (sslSocket);
144
69
70
		init();		// to complete connection establishment
71
		
72
		return true;
73
    }
74
    
75
	public int createDataConnection(int direction) throws IOException, SecureConnectionRequiredException {
76
		Socket dataSock = connectSocket();
77
		if (dataSock == null) throw new IOException();
78
79
		int dataConnectionId = -1;
80
		boolean securityRequired = false;
81
82
		try {
83
			dataConnectionId = initDataConnection(dataSock, direction);
84
		} catch (SecureConnectionRequiredException e) {
85
			securityRequired = true;
86
		}
87
		
88
		if (!securityRequired) return dataConnectionId;
89
		
90
		SSLSocket sslDataSock = initSSL(dataSock);
91
		
92
		return initDataConnection(sslDataSock, direction);
93
	}
145
}
94
}
(-)src/org/eclipse/tptp/platform/execution/client/core/internal/NodeImpl.java (-56 / +30 lines)
Lines 14-41 Link Here
14
14
15
package org.eclipse.tptp.platform.execution.client.core.internal;
15
package org.eclipse.tptp.platform.execution.client.core.internal;
16
16
17
import java.io.IOException;
18
import java.net.InetAddress;
17
import java.net.InetAddress;
19
import java.net.UnknownHostException;
18
import java.net.UnknownHostException;
20
import java.util.Enumeration;
21
import java.util.Hashtable;
19
import java.util.Hashtable;
22
import java.util.Vector;
20
import java.util.Vector;
23
21
24
import org.eclipse.core.runtime.Platform;
22
import org.eclipse.core.runtime.Platform;
25
import org.eclipse.tptp.platform.execution.client.core.*;
23
import org.eclipse.tptp.platform.execution.client.core.*;
26
import org.eclipse.tptp.platform.execution.util.*;
27
import org.eclipse.tptp.platform.execution.util.internal.*;
24
import org.eclipse.tptp.platform.execution.util.internal.*;
28
import org.eclipse.tptp.platform.execution.security.*;
25
import org.eclipse.tptp.platform.execution.security.*;
29
import org.eclipse.tptp.platform.execution.exceptions.*;
26
import org.eclipse.tptp.platform.execution.exceptions.*;
30
import org.eclipse.tptp.platform.iac.administrator.internal.startstop.AutoStartStop;
27
import org.eclipse.tptp.platform.iac.administrator.internal.startstop.AutoStartStop;
31
import org.osgi.framework.Bundle;
28
import org.osgi.framework.Bundle;
32
29
33
34
35
public class NodeImpl implements INode {
30
public class NodeImpl implements INode {
36
37
    private static final int DEFAULT_LIST_PROCESS_TIMEOUT = 7000;
38
39
	protected String _name;
31
	protected String _name;
40
	protected InetAddress[] _addr;
32
	protected InetAddress[] _addr;
41
	protected Vector _listeners=new Vector(10);
33
	protected Vector _listeners=new Vector(10);
Lines 53-62 Link Here
53
		try {
45
		try {
54
			_addr=InetAddress.getAllByName(addr.getHostName());
46
			_addr=InetAddress.getAllByName(addr.getHostName());
55
		}
47
		}
56
		catch(Exception e) {
48
		catch(Exception e) {}
57
58
		}
59
60
	}
49
	}
61
50
62
	public NodeImpl(String name, InetAddress[] addr) {
51
	public NodeImpl(String name, InetAddress[] addr) {
Lines 95-105 Link Here
95
	 * @see Node#isConnected()
84
	 * @see Node#isConnected()
96
	 */
85
	 */
97
	public boolean isConnected() {
86
	public boolean isConnected() {
98
		if(_ac!=null) {
87
		return _ac != null;
99
			//return _ac.isActive();
100
			return true;
101
		}
102
		return false;
103
	}
88
	}
104
89
105
	/**
90
	/**
Lines 120-191 Link Here
120
			
105
			
121
		IConnection _connection = null;
106
		IConnection _connection = null;
122
		int tryCount = 0;
107
		int tryCount = 0;
123
		int ret = -1;
108
		if(_ac == null) {
124
		if(_ac==null) 
109
			do {
125
		{
110
				try {
126
			do
111
					_connection = ConnectionFactory.createConnection(this, connInfo); 
127
			{
128
				try 
129
				{
130
					_connection=new ConnectionImpl();
131
					_connection.connect(this, connInfo);					
132
					if (tryCount == Constants.CONNECT_TIMEOUT_TRY_COUNT)
112
					if (tryCount == Constants.CONNECT_TIMEOUT_TRY_COUNT)
133
					{
113
					{
134
						throw new TimeoutException(Constants.TPTP_PLATFORM_EXEC_MSG21);
114
						throw new TimeoutException(Constants.TPTP_PLATFORM_EXEC_MSG21);
135
					}
115
					}
136
					tryCount++;
116
					tryCount++;
137
				}
117
				}
118
				catch (LoginFailedException e) {
119
					throw e;
120
				}
138
				catch (ReconnectRequestedException e) {
121
				catch (ReconnectRequestedException e) {
139
					connInfo.setPort(e.getReconnectPort());
122
					connInfo.setPort(e.getReconnectPort());
140
					tryCount = 0;
123
					tryCount = 0;
141
					_connection=null;
124
					_connection=null;
142
				}
125
				}
143
				catch(Exception e) {
126
				catch(Exception e) {
144
					_connection=null;
127
					_connection = null;
145
					if (Constants.TPTP_DEBUG) System.out.println("The NodeIml connect exception - " + e);
128
					if (Constants.TPTP_DEBUG) System.out.println("The NodeIml connect exception - " + e);
146
					throw new AgentControllerUnavailableException(Constants.TPTP_PLATFORM_EXEC_MSG22 + e.getMessage());
129
					throw new AgentControllerUnavailableException(Constants.TPTP_PLATFORM_EXEC_MSG22 + e.getMessage());
147
				}
130
				}
148
			}
131
			}
149
			while(_connection == null);
132
			while(_connection == null);
150
		}
133
		}
151
		if(_connection != null)
134
		
152
		{
135
		if(_connection != null) {
153
			_ac = new AgentController(this, connInfo);
136
			_ac = new AgentController(this, connInfo);
154
			((AgentController)_ac).setConnection(_connection);
137
			((AgentController)_ac).setConnection(_connection);
155
			return _ac;
138
		} 
156
		}
157
		
139
		
158
		return _ac;
140
		return _ac;
159
	}
141
	}
160
	
142
	
161
	public synchronized IAgentController connect(ConnectionInfo connInfo, User user) throws AgentControllerUnavailableException, SecureConnectionRequiredException, UntrustedAgentControllerException, LoginFailedException
143
	public synchronized IAgentController connect(ConnectionInfo connInfo, User user) throws AgentControllerUnavailableException, SecureConnectionRequiredException, UntrustedAgentControllerException, LoginFailedException	{
162
	{
144
		if (!isConnected()) connect(connInfo);
163
		boolean userAuthenticated = false;
145
		if (_ac == null) return null;
164
		connect(connInfo);
165
		
146
		
166
		try 
147
		try {
167
		{
148
			_ac.authenticateUser(user);
168
			if (_ac != null)
149
		} catch (Exception e) {
169
			{
150
			throw new AgentControllerUnavailableException();
170
				userAuthenticated = _ac.authenticateUser(user);
171
			}
172
			
173
			if (userAuthenticated)
174
			{
175
				return _ac;
176
			}
177
		}
178
		catch(Exception e) 
179
		{
180
			
181
			throw new AgentControllerUnavailableException(Constants.TPTP_PLATFORM_EXEC_MSG22);
182
		}
151
		}
183
		
152
184
		return null;
153
		return _ac;
185
	}
154
	}
186
	
155
	
187
	public IAgentController getAgentController(int port)
156
	public IAgentController getAgentController(int port) {
188
	{
189
		return _ac;
157
		return _ac;
190
	}
158
	}
191
	
159
	
Lines 204-208 Link Here
204
172
205
		return isLocal;
173
		return isLocal;
206
	}
174
	}
175
	
176
	public void disconnect() {
177
		if (_ac != null) { 
178
			_ac.disconnect();  
179
			_ac = null; 
180
		}
181
	}
207
}
182
}
208
(-)src/org/eclipse/tptp/platform/execution/client/core/internal/AgentController.java (-83 / +36 lines)
Lines 122-192 Link Here
122
		return _connection.getNextContextId();
122
		return _connection.getNextContextId();
123
	}
123
	}
124
	
124
	
125
	public void disconnect()
125
	public void disconnect() {
126
	{
126
		if (_connection != null) {
127
		_connection.disconnect();
127
			_connection.disconnect();
128
			_connection = null;
129
		}
130
		
131
		isConnected = false;
128
	}
132
	}
129
133
130
	/*
134
	/*
131
	 * Authenticate the User Credentials with AC
135
	 * Authenticate the User Credentials with AC
132
	 *
136
	 *
133
	 */
137
	 */
134
	public boolean authenticateUser(User user) throws NotConnectedException
138
	public boolean authenticateUser(User user) throws NotConnectedException {
135
	{
139
		if(!isConnected) throw new NotConnectedException(Constants.TPTP_PLATFORM_EXEC_MSG6);
136
		boolean userAuthenticated = false;
137
		final Object _launcherLock 	= new Object();
138
		final Object _eclipseLock 	= new Object();
139
		boolean _requireEclipseLock = false;
140
		if(!isConnected)throw new NotConnectedException(Constants.TPTP_PLATFORM_EXEC_MSG6);
141
		IAgent[] retagent = null;
142
		final GenericCommandHandler genCmdHandler = new GenericCommandHandler();
143
140
144
		synchronized(_launcherLock) 
141
		return ((ConnectionImpl)_connection).authenticateUser(user);
145
		{
146
 		   	_requireEclipseLock=false;
147
			StringBuffer AuthenticateUserCommand = new StringBuffer("");
148
			try
149
			{					
150
				AuthenticateUserCommand.append("<authenticateUser iid=\"org.eclipse.tptp.agentManager\"><userName>");
151
				AuthenticateUserCommand.append(user.getName());
152
				AuthenticateUserCommand.append("</userName><password>");
153
				AuthenticateUserCommand.append(user.getPassword());
154
				AuthenticateUserCommand.append("</password></authenticateUser>");
155
			   	this.sendCommand(AuthenticateUserCommand.toString(), Constants.AC_DEST_ID, new ICommandHandler()
156
			   	{
157
			   		public void incomingCommand(INode node, ICommandElement command)
158
			   		{
159
			   			genCmdHandler.setCommandElement(command);
160
			   		}
161
			   	});
162
				_requireEclipseLock=true;
163
				_launcherLock.wait(Constants.TIMEOUT_PERIOD);
164
			}
165
			catch(InterruptedException e) 
166
			{
167
				e.printStackTrace();
168
			}
169
			catch(Exception e)
170
			{
171
				e.printStackTrace();
172
			}
173
		}
174
	 	if (genCmdHandler.getCommandElement() != null) 
175
		{
176
		 	String commandStr = ((CommandFragment)genCmdHandler.getCommandElement()).getCommandData();
177
			TPTPXMLParse ParseObj = new TPTPXMLParse();
178
			ParseObj.setParser(commandStr);
179
			Hashtable CommandHash = ParseObj.getHashTable();
180
			if (CommandHash.containsKey("userAuthenticated"))
181
			{
182
				userAuthenticated = true;
183
			}
184
			else if (CommandHash.containsKey("authenticationFailed"))
185
			{
186
				userAuthenticated = false;
187
			}
188
		}
189
		return userAuthenticated;
190
	}
142
	}
191
	
143
	
192
	/* (non-Javadoc)
144
	/* (non-Javadoc)
Lines 1340-1371 Link Here
1340
	/* (non-Javadoc)
1292
	/* (non-Javadoc)
1341
	 * @see org.eclipse.tptp.platform.execution.core.IAgentController#sendCommand(java.lang.String, int, org.eclipse.tptp.platform.execution.core.ICommandHandler)
1293
	 * @see org.eclipse.tptp.platform.execution.core.IAgentController#sendCommand(java.lang.String, int, org.eclipse.tptp.platform.execution.core.ICommandHandler)
1342
	 */
1294
	 */
1343
	public void sendCommand(String cmd, int destID, ICommandHandler handler) throws IOException
1295
	public void sendCommand(String cmd, int destID, ICommandHandler handler) throws IOException {
1344
	{
1296
		try		{
1345
		try
1297
			ControlMessage message = new ControlMessage();
1346
		{
1298
			message.setMessageType(Constants.TPTP_AC_MESSAGE);
1347
		ControlMessage message = new ControlMessage();
1299
			message.setMagicNumber(Constants.AC_MAGIC_NUMBER);
1348
		message.setMessageType(Constants.TPTP_AC_MESSAGE);
1300
			message.setFlags(0);
1349
		message.setMagicNumber(Constants.AC_MAGIC_NUMBER);
1301
			
1350
		message.setFlags(0);
1302
			CommandFragment cmdFrag = new CommandFragment();
1351
		CommandFragment cmdFrag = new CommandFragment();
1303
			cmdFrag.setDestination(destID);
1352
		cmdFrag.setDestination(destID);
1304
			cmdFrag.setSource(this._sourceID);
1353
		cmdFrag.setSource(this._sourceID);
1305
			cmdFrag.setContext(_connection.getNextContextId());
1354
		cmdFrag.setContext(_connection.getNextContextId());
1306
			cmdFrag.setCommand(cmd);
1355
		cmdFrag.setCommand(cmd);
1307
			cmdFrag.buildCommand();//Build the command in ConnectionImpl::sendMessage as we don't know the context at this place
1356
		cmdFrag.buildCommand();//Build the command in ConnectionImpl::sendMessage as we don't know the context at this place
1308
			message.appendCommand(cmdFrag);
1357
		message.appendCommand(cmdFrag);
1358
1309
1359
		if (handler == null)
1310
			if (handler == null) {
1360
		{
1361
			//this.getConnection().sendMessage(message, this.acCommandHandler);
1311
			//this.getConnection().sendMessage(message, this.acCommandHandler);
1362
		}
1312
			}
1363
		else
1313
			else {
1364
		{
1314
				getConnection().sendMessage(message, handler);
1365
			this.getConnection().sendMessage(message, handler);
1315
			}
1366
		}
1316
			
1367
		}catch(Exception e){e.printStackTrace();}
1317
		} catch(Exception e){e.printStackTrace();}
1368
	}
1318
	}
1319
	
1369
	/** 
1320
	/** 
1370
	 * Sends a command to the specified destination, the command requires a control message object
1321
	 * Sends a command to the specified destination, the command requires a control message object
1371
	 * and a commandhandler 
1322
	 * and a commandhandler 
Lines 1599-1604 Link Here
1599
			this.value = value;
1550
			this.value = value;
1600
		}
1551
		}
1601
	}
1552
	}
1553
	
1554
	public boolean isAuthenticated() {
1555
		return _connection != null && ((ConnectionImpl)_connection).isAuthenticated(); 
1556
	}
1602
}
1557
}
1603
1604
(-)src/org/eclipse/tptp/platform/execution/client/core/internal/ConnectionImpl.java (-423 / +417 lines)
Lines 28-33 Link Here
28
import java.util.Hashtable;
28
import java.util.Hashtable;
29
29
30
import org.eclipse.tptp.platform.execution.client.core.*;
30
import org.eclipse.tptp.platform.execution.client.core.*;
31
import org.eclipse.tptp.platform.execution.client.core.internal.commands.AuthenticateCommand;
32
import org.eclipse.tptp.platform.execution.security.User;
31
import org.eclipse.tptp.platform.execution.util.*;
33
import org.eclipse.tptp.platform.execution.util.*;
32
import org.eclipse.tptp.platform.execution.util.internal.CommandFragment;
34
import org.eclipse.tptp.platform.execution.util.internal.CommandFragment;
33
import org.eclipse.tptp.platform.execution.util.internal.Constants;
35
import org.eclipse.tptp.platform.execution.util.internal.Constants;
Lines 37-46 Link Here
37
import org.eclipse.tptp.platform.execution.exceptions.*;
39
import org.eclipse.tptp.platform.execution.exceptions.*;
38
40
39
public class ConnectionImpl implements IConnection {
41
public class ConnectionImpl implements IConnection {
40
41
	protected Socket _socket;
42
	protected Socket _socket;
42
	protected INode _node;
43
	protected INode _node;
43
	protected int _port;
44
	protected int _port;
45
	protected InetAddress inetAddress = null;
44
	
46
	
45
	private int _connectionId = 0;
47
	private int _connectionId = 0;
46
48
Lines 51-254 Link Here
51
	private boolean _isComplete = false;
53
	private boolean _isComplete = false;
52
54
53
	private final Vector _listeners = new Vector();
55
	private final Vector _listeners = new Vector();
54
	private final Object _connectionLock = new Object();
55
	private final Object _loginLock = new Object();
56
56
57
	private static final Object writeLock = new Object();
58
	private static final Object writeDataLock = new Object();
57
	private static final Object contextLock = new Object();
59
	private static final Object contextLock = new Object();
60
	private static final Object authLock = new Object();
58
	private boolean _isInitialized		= false;
61
	private boolean _isInitialized		= false;
59
	private boolean _loginPending 		= false;
62
	private boolean isAuthenticated = false;
60
	private ReconnectRequestedException _reconnectRequestedException=null;
61
	private SecureConnectionRequiredException _secureConnectionRequiredException=null;
62
	private LoginFailedException _loginFailed=null;
63
63
64
	private int _soTimeout = Constants.TIMEOUT_PERIOD;
64
	private int _soTimeout = Constants.TIMEOUT_PERIOD;
65
65
66
	class DataConnection
66
	class DataConnection {				// it is better to move all processing of data connections to AC or Node
67
	{
68
		private Socket _dataSocket;
67
		private Socket _dataSocket;
69
		private ACTCPDataServer _dataServer;
68
		private ACTCPDataServer _dataServer;
69
		private int dataConnectionId;
70
		
70
		
71
		public void setDataSocket(Socket dataSocket){_dataSocket = dataSocket;}
71
		public void setDataSocket(Socket dataSocket) { _dataSocket = dataSocket; }
72
		public void setDataServer(ACTCPDataServer dataServer){_dataServer = dataServer;}
72
		public void setDataServer(ACTCPDataServer dataServer) { _dataServer = dataServer; }
73
		public Socket getDataSocket(){return _dataSocket;}
73
		public Socket getDataSocket() { return _dataSocket; }
74
		public ACTCPDataServer getDataServer(){return _dataServer;}
74
		public ACTCPDataServer getDataServer() { return _dataServer; }
75
		public int getDataConnectionId() { return dataConnectionId; }
76
		public void setDataconnectionId(int dataConnectionId) { this.dataConnectionId = dataConnectionId; }
75
	}
77
	}
76
	
78
	
77
	public ConnectionImpl() {
79
	public ConnectionImpl() {
78
		super();
79
	}
80
	}
80
	
81
81
	public int getConnectionId()
82
	public int getConnectionId() {
82
	{
83
		return _connectionId;
83
		return this._connectionId;
84
	}
84
	}
85
	
85
	
86
	public boolean isNewAC()
86
	public boolean isNewAC() {
87
	{
88
		return true;
87
		return true;
89
	}
88
	}
90
	
89
	
91
	public long getNextContextId()
90
	public long getNextContextId() {
92
	{
93
		synchronized(contextLock){
91
		synchronized(contextLock){
94
			return _context++;
92
			return _context++;
95
		}
93
		}
96
	
97
	}
94
	}
98
	
95
	
99
	public void addContext(long contextID, ICommandHandler handler)
96
	public void addContext(long contextID, ICommandHandler handler)	{
100
	{
101
		synchronized(contextLock){
97
		synchronized(contextLock){
102
			this._contextMapper.addContext(contextID, handler);
98
			this._contextMapper.addContext(contextID, handler);
103
		}
99
		}
104
	}
100
	}
105
101
106
	public void connect(INode node, ConnectionInfo connInfo) throws IOException, SecureConnectionRequiredException, LoginFailedException, UntrustedAgentControllerException, ReconnectRequestedException
102
	protected Socket connectSocket () throws IOException {
107
	{
103
		if (_node == null) return null;
108
		_port=connInfo.getPort();
104
		return connectSocket(_node.getAllInetAddresses(), _port);
105
	}
106
	
107
	protected Socket connectSocket (InetAddress addrs[], int port) throws IOException {
108
		if (addrs == null || addrs.length <= 0) return null;
109
110
		Socket socket = null;
111
		
112
		for (int i=0; i<addrs.length; i++) {
113
			if(Constants.TPTP_DEBUG) System.out.println("Connecting to " + addrs[i] + " at port " + _port);
114
			socket = new Socket(addrs[i], port);
115
			socket.setSoTimeout(_soTimeout);
116
			socket.setTcpNoDelay(true);
117
			inetAddress = addrs[i];
118
			break;
119
		}
120
121
		return socket;
122
	}
123
	
124
	public void connect(INode node, ConnectionInfo connInfo) throws IOException, SecureConnectionRequiredException, 
125
		LoginFailedException, UntrustedAgentControllerException, ReconnectRequestedException {
126
		
109
		_soTimeout = connInfo.getSoTimeout();
127
		_soTimeout = connInfo.getSoTimeout();
110
		int offset=0;
128
		if (_soTimeout > 0) _soTimeout *= Constants.CONNECT_TIMEOUT_TRY_COUNT;
111
		InetAddress[] addrs=node.getAllInetAddresses();
129
		
130
		_node = node;
131
		_port = connInfo.getPort();
112
132
113
		do {
133
		_socket = connectSocket(node.getAllInetAddresses(), _port); 
114
			/* Connect to the remote machine */
134
		if (_socket == null) throw new IOException();
115
			try {
116
				if(Constants.TPTP_DEBUG)System.out.println("Connecting to " + addrs[offset] + " at port " + _port);
117
				_socket=new Socket(addrs[offset], _port);
118
				
119
				sendConnectCommand();
120
				break;
121
			}
122
			catch(IOException e) {
123
				offset++;
124
				if (Constants.TPTP_DEBUG)System.out.println(e.getMessage());
125
				if(offset==addrs.length) {
126
					if (Constants.TPTP_DEBUG)System.out.println("Error while connecting to the Agent Controller on " + addrs[offset] + " running at port " + _port);
127
					throw e;
128
				}
129
			}
130
		}while(offset<addrs.length);
131
		_node=node;
132
		
135
		
133
		this.init();
136
		init();
134
		
137
		
135
		// We expected to have a connectionID by now.  If we don't, it's because the wait above timed out
138
		// We expected to have a connectionID by now.  If we don't, it's because the wait above timed out
136
		if ( _connectionId == 0 ) {
139
		if (_connectionId == 0) {
137
       		throw new LoginFailedException("Timeout while waiting for connection to complete");
140
       		throw new LoginFailedException("Timeout while waiting for connection to complete");
138
		}
141
		}
139
	}
142
	}
140
	public void connect(INode node, int port) throws IOException, SecureConnectionRequiredException, LoginFailedException, UntrustedAgentControllerException, ReconnectRequestedException
143
	
141
	{
144
	public void connect(INode node, int port) throws IOException, SecureConnectionRequiredException, LoginFailedException, UntrustedAgentControllerException, ReconnectRequestedException {
142
		ConnectionInfo connInfo = new ConnectionInfo();
145
		ConnectionInfo connInfo = new ConnectionInfo();
143
		connInfo.setPort(port);
146
		connInfo.setPort(port);
144
		connect( node, connInfo );
147
		connect(node, connInfo);
145
	}
146
	
147
	protected void sendConnectCommand() throws IOException
148
	{
149
		if(Constants.TPTP_DEBUG)System.out.println("The AC is New");					
150
		sendControlCommand(Constants.CONNECT);
151
	}
148
	}
152
149
153
150
	protected void init() throws SecureConnectionRequiredException, LoginFailedException, IOException, ReconnectRequestedException {
154
	/* Init */
151
		_contextMapper = new ContextMapper();
155
	protected void init() throws SecureConnectionRequiredException, LoginFailedException, IOException, ReconnectRequestedException
156
	{
157
		try 
158
		{
159
			_socket.setSoTimeout(_soTimeout);
160
			_socket.setTcpNoDelay(true);
161
		}
162
		catch(SocketException e) {
163
			/* We can ignore this */
164
		}
165
166
		_contextMapper=new ContextMapper();
167
		_dataConnectionMap = new Hashtable();
152
		_dataConnectionMap = new Hashtable();
168
		_cmdHandler=new ICommandHandler() 
153
		
169
		{
154
		_cmdHandler = new ICommandHandler() {
170
			public void incomingCommand(INode node, ICommandElement command) 
155
			public void incomingCommand(INode node, ICommandElement command) {
171
			{
172
				handleACCommands(command);
156
				handleACCommands(command);
173
			}
157
			}
174
		};
158
		};
175
159
176
		/* RKD:  With the V5 RAC it first accepts the socket connection and then determines is the connection
160
		sendControlCommand(Constants.CONNECT);
177
		 * is allowed.  If the connection is not allowed the the connection is cut.  We need to first connect
161
178
		 * and then determine if we have been cut off.  The connection has already occurred above us in the
162
		byte rbuf[] = new byte[512];
179
		 * stack.  We then will wait until either a read timeout has occured on the reader thread or the
163
		BufferedInputStream inStream = new BufferedInputStream(_socket.getInputStream());
180
		 * connection gets cut by the other side.
164
		int offset = 0;
181
		 */
165
182
166
		while (true) {
183
		synchronized(_connectionLock) {
167
			int bytesRead = inStream.read(rbuf, offset, rbuf.length-offset);
184
			SocketReaderThread reader=new SocketReaderThread();
168
185
			reader.setName(_node.getName()+"_connection");
169
			if(bytesRead < 0) break;
186
			reader.setDaemon(true);
170
187
			reader.start();
171
	        if (offset > 0) {
188
			try 
172
	        	bytesRead += offset;
189
			{
173
				offset = 0;
190
				_connectionLock.wait();
174
	        }
191
			}
192
			catch(InterruptedException e){e.printStackTrace();}
193
194
			_isInitialized=true;
195
196
			if (_reconnectRequestedException!=null) {
197
				ReconnectRequestedException temp=_reconnectRequestedException;
198
				_reconnectRequestedException = null;
199
				throw temp;
200
			}
201
			
175
			
202
			/* If this connection has a pending exception because the server is secure we need to throw the
176
			 // If we've tried to connect to a backward compatibility
203
			 * exception so that the caller can create a new connection with the proper security settings.
177
			 // layer of the AC, we'll immediately get a response in 
204
			 */
178
			 // RAC format.  If we ignore this, the BC layer will
205
			if(_secureConnectionRequiredException!=null) {
179
			 // respond to our first message by giving us the port
206
				SecureConnectionRequiredException temp=_secureConnectionRequiredException;
180
			 // to connect to the regular socket TL.
207
				_secureConnectionRequiredException=null;
181
			 //
208
				_loginPending=false;
182
			int v = checkForRACMessage(rbuf, offset);
209
				throw temp;
183
			if(v >= 0) {
184
				// We read the header, the next four bytes will be the length 
185
				// (including the header) of the RAC message
186
				int len = (int) TPTPMessageUtil.readTPTPLongFromBuffer(rbuf, v);
187
				if (len == bytesRead) {
188
					offset = 0;
189
					continue;
190
				}
191
				
192
				if (len > bytesRead) {
193
					inStream.skip(len - bytesRead);
194
					offset = 0;
195
					continue;
196
				}
197
198
				offset = len;
199
			}
200
201
				// First we make sure we have at least enough read for the message header.
202
				  // If not, compress and re-read.
203
			//
204
			if (bytesRead-offset < Constants.AC_MESSAGE_HEADER_SIZE) {
205
				System.arraycopy(rbuf, offset, rbuf, 0, bytesRead-offset);
206
				offset = bytesRead - offset;
207
				continue;
210
			}
208
			}
209
			
210
				// We have the header information, now lets try and get the entire message.  Once
211
				 //  again the same error conditions can occur.
212
				//
213
				//System.out.println("Offset xx::"+new String(buffer));
211
214
212
			//System.out.println("init - 7");
215
			ControlMessage msg=new ControlMessage();
213
			synchronized(_loginLock) {
216
			msg.setMessageType(Constants.TPTP_AC_MESSAGE);
214
				if(_loginPending) {
217
			int current;
215
					try {
218
				
216
						_loginLock.wait();
219
			try {
220
				if (rbuf.length == bytesRead + offset) {
221
					current = msg.readFromBuffer(rbuf, offset);
222
				}
223
				else {
224
					// length is not passed to readFromBuffer so we should ensure 
225
					// that readFromBuffer will not read trash from the end of the buffer
226
					// and no exception will be thrown.
227
					// ControlMessage.readFromBuffer(buffer, offset, length) method
228
					// is needed in order to prevent extra memory allocations in this case.
229
					byte[] buffer2 = new byte[bytesRead];
230
					System.arraycopy(rbuf, offset, buffer2, 0, bytesRead);
231
					current = msg.readFromBuffer(buffer2, 0);
232
				}
233
			} catch (Exception e) {
234
				throw new IOException();
235
			}
236
			
237
			long flags = msg.getFlags();
238
			if ((flags & Constants.CONNECTION_COMPLETE) != 0) {
239
				isAuthenticated = (flags & Constants.AUTHENTICATION_FAILED) == 0;
240
				_connectionId = extractConnectionId(rbuf, current);
241
				break;
242
			}								// equals - since CONNECTION_RECONNECT_REQUEST has two bits set
243
			else if ((flags & Constants.CONNECTION_REFUSED) != 0) {
244
				if ((flags & Constants.SECURITY_REQUIRED) != 0) {
245
					throw new SecureConnectionRequiredException();
246
				}
247
				else if((flags & Constants.CONNECTION_RECONNECT_REQUEST) == Constants.CONNECTION_RECONNECT_REQUEST) {
248
					int portreq = -1;
249
	    		
250
					try	{
251
						close();
252
						CommandFragment cmd = (CommandFragment)msg.getCommand(0);
253
						String strToParse = cmd.getCommandData();
254
						TPTPXMLParse ParseObj = new TPTPXMLParse();
255
						ParseObj.setParser(strToParse.trim());
256
						Hashtable CommandHash = ParseObj.getHashTable();
257
						if(CommandHash.containsKey("port")) {
258
							portreq = Integer.parseInt((String)ParseObj.getHashTable().get("port"));
259
						}
217
					}
260
					}
218
					catch(InterruptedException e) {
261
					catch(Exception e){}
219
						/* We should ignore this */
262
		    	 			
263
					if(portreq == -1) {
264
						// This is a bad situation.  The AC should have given us a port
265
						// Since it didn't (unexpectedly), let's try a default
266
						portreq = 10006;
220
					}
267
					}
268
					
269
					// Tell the caller how to reconnect
270
					throw new ReconnectRequestedException(portreq);
221
				}
271
				}
272
				
273
				throw new IOException("Connection Refused");
222
			}
274
			}
223
275
			
224
			if(_loginFailed!=null) {
276
			throw new IOException("Unknown command");
225
				LoginFailedException temp=_loginFailed;
226
				_loginFailed=null;
227
				_loginPending=false;
228
				throw temp;
229
			}
230
			if(_isComplete) {
231
				throw new IOException();
232
			}
233
		}
277
		}
278
		
279
    	(new SocketReaderThread()).start();
234
	}
280
	}
235
281
	
236
	private void handleACCommands(ICommandElement command)
282
	private void handleACCommands(ICommandElement command) {
237
	{
238
		long contextId=command.getContext();
283
		long contextId=command.getContext();
239
		if(Constants.TPTP_DEBUG)System.out.println("The context of the returned command:" + contextId);
284
		if(Constants.TPTP_DEBUG)System.out.println("The context of the returned command:" + contextId);
240
		
285
		
241
		//Find the command handler associated with this contextId and
286
		//Find the command handler associated with this contextId and
242
		// forward the message appropriately.
287
		// forward the message appropriately.
243
		ICommandHandler ch=_contextMapper.getHandler(contextId);
288
		ICommandHandler ch=_contextMapper.getHandler(contextId);
244
		if(ch != null) 
289
		if(ch != null) {
245
		{
246
			if(Constants.TPTP_DEBUG)System.out.println("Forwarding to command handler");
290
			if(Constants.TPTP_DEBUG)System.out.println("Forwarding to command handler");
247
			ch.incomingCommand(_node, command);
291
			ch.incomingCommand(_node, command);
248
		}	
292
		}	
249
		else {
250
			if(Constants.TPTP_DEBUG)System.out.println("Could not find command handler");
251
		}
252
	}
293
	}
253
	
294
	
254
	private int extractConnectionId(byte[] buffer, int offset)
295
	private int extractConnectionId(byte[] buffer, int offset)
Lines 273-280 Link Here
273
	 *    nonzero if error
314
	 *    nonzero if error
274
	 *
315
	 *
275
	 *********************************************************/
316
	 *********************************************************/
276
	private void sendCONNECT_DATACommand(Socket datasock, int direction) throws IOException 
317
	private void sendCONNECT_DATACommand(Socket datasock, int direction) throws IOException	{
277
	{
278
		long flags = 0 ;
318
		long flags = 0 ;
279
319
280
		/* build the CONNECT command string */
320
		/* build the CONNECT command string */
Lines 291-297 Link Here
291
		long dataPathType = direction;
331
		long dataPathType = direction;
292
		offset = TPTPMessageUtil.writeTPTPLongToBuffer(buffer, offset, dataPathType);		
332
		offset = TPTPMessageUtil.writeTPTPLongToBuffer(buffer, offset, dataPathType);		
293
		
333
		
294
		OutputStream stream=datasock.getOutputStream();
334
		OutputStream stream = datasock.getOutputStream();
295
		stream.write(buffer);		
335
		stream.write(buffer);		
296
		stream.flush();
336
		stream.flush();
297
	}
337
	}
Lines 308-315 Link Here
308
	 *    nonzero if error
348
	 *    nonzero if error
309
	 *
349
	 *
310
	 *********************************************************/
350
	 *********************************************************/
311
	private void sendControlCommand(long commandFlags) throws IOException 
351
	private void sendControlCommand(long commandFlags) throws IOException  {
312
	{
313
		long flags = 0 ;
352
		long flags = 0 ;
314
353
315
		/* build the CONNECT command string */
354
		/* build the CONNECT command string */
Lines 324-427 Link Here
324
		sendMessage(connectMessage, _cmdHandler);
363
		sendMessage(connectMessage, _cmdHandler);
325
	}	
364
	}	
326
365
366
	int createDataConnection(int direction) throws IOException, SecureConnectionRequiredException {
367
		Socket datasock = connectSocket();
368
		if (datasock == null) throw new IOException();
327
369
328
	int createDataConnection(int direction) throws IOException
370
		return initDataConnection(datasock, direction);
329
	{
371
	}
330
		Socket datasock = null;
372
	
331
		int dataConnectionId = -1;
373
	protected int initDataConnection(Socket datasock, int direction) throws IOException, SecureConnectionRequiredException {
332
		byte[] buffer=new byte[Constants.MAX_MESSAGE_LENGTH];
374
		if (datasock == null || !datasock.isConnected()) return -1;
333
		int masterOffset=0;
334
		
375
		
335
		int offset=0;
376
		// CONNECT_DATA command 
336
		InetAddress[] addrs=_node.getAllInetAddresses();
337
338
		do {
339
			/* Connect to the remote machine */
340
			try {
341
					datasock=new Socket(addrs[offset], _port);
342
					datasock.setTcpNoDelay(true);
343
					datasock.setSoTimeout(_soTimeout);
344
					break;
345
			}
346
			catch(IOException exp)
347
			{
348
				offset++;
349
				//System.out.println(e.getMessage());
350
				if(offset==addrs.length) {
351
					throw exp;
352
				}
353
			}
354
		}while(offset<addrs.length);
355
356
		/* CONNECT_DATA command */
357
		sendCONNECT_DATACommand(datasock, direction);
377
		sendCONNECT_DATACommand(datasock, direction);
358
		
378
359
		/* Get the InputStream for this socket so we can read some data */
379
		// Get the InputStream for this socket so we can read some data 
360
		InputStream inStream=datasock.getInputStream();
380
		byte[] buffer = new byte[256];
361
		int bytesRead=inStream.read(buffer, masterOffset, buffer.length-masterOffset);
381
		InputStream inStream = datasock.getInputStream();
382
		int d = inStream.read(buffer, 0, buffer.length);
362
		
383
		
363
		ControlMessage DataConnectionResponseMessage = new ControlMessage();
384
		ControlMessage DataConnectionResponseMessage = new ControlMessage();
364
		DataConnectionResponseMessage.setMessageType(Constants.TPTP_AC_MESSAGE);
385
		DataConnectionResponseMessage.setMessageType(Constants.TPTP_AC_MESSAGE);
365
		masterOffset = DataConnectionResponseMessage.readFromBuffer(buffer, masterOffset);
386
		int masterOffset = DataConnectionResponseMessage.readFromBuffer(buffer, 0);
366
		long flags = DataConnectionResponseMessage.getFlags();
387
		long flags = DataConnectionResponseMessage.getFlags();
367
		if ((flags & Constants.DATA_CONNECTION_COMPLETE) != 0)
388
		if ((flags & Constants.CONNECTION_REFUSED) != 0) {
368
    	{
389
			if ((flags & Constants.SECURITY_REQUIRED) != 0) {
369
			dataConnectionId = extractConnectionId(buffer, masterOffset);
390
				throw new SecureConnectionRequiredException();
370
    	}
391
			}
392
			
393
			throw new IOException("Connection Refused");
394
		}
395
		
396
		if ((flags & Constants.DATA_CONNECTION_COMPLETE) <= 0) return -1;
397
		
398
		int dataConnectionId = extractConnectionId(buffer, masterOffset);
399
		if (dataConnectionId <= 0) return -1;
371
		
400
		
372
		DataConnection dataConnectionInfo = new DataConnection();
401
		DataConnection dataConnectionInfo = new DataConnection();
373
		ACTCPDataServer dataServer = new ACTCPDataServer();
402
		ACTCPDataServer dataServer = new ACTCPDataServer();
374
		if (dataConnectionId > 0)
375
		{
376
			//dataConnectionId = ::getConnectionId(pMsg) ;
403
			//dataConnectionId = ::getConnectionId(pMsg) ;
377
			if(Constants.TPTP_DEBUG)System.out.println("The Data Channel ConnectionID: " + dataConnectionId);
404
		if(Constants.TPTP_DEBUG)System.out.println("The Data Channel ConnectionID: " + dataConnectionId);
378
			dataConnectionInfo.setDataSocket(datasock);
405
		dataConnectionInfo.setDataSocket(datasock);
379
			dataConnectionInfo.setDataServer(dataServer);
406
		dataConnectionInfo.setDataServer(dataServer);
380
			_dataConnectionMap.put(new Integer(dataConnectionId), dataConnectionInfo);				
407
		dataConnectionInfo.setDataconnectionId(dataConnectionId);
381
		
408
		_dataConnectionMap.put(new Integer(dataConnectionId), dataConnectionInfo);				
382
			try
409
		
383
			{
410
		try {
384
				dataServer.startServer(null, datasock);
411
			dataServer.startServer(null, datasock);
385
			}
412
		}
386
			catch(SocketException sockExp)
413
		catch(SocketException sockExp) {			
387
			{			
414
		}
388
				System.out.println("Error starting the TCPDataServer");
415
		catch(IOException Exp) {			
389
			}
390
			catch(IOException Exp)
391
			{			
392
				System.out.println("Error starting the TCPDataServer");
393
			}
394
		}
416
		}
395
		
417
		
396
		return dataConnectionId;
418
		return dataConnectionId;
397
	}
419
	}
398
420
399
	
421
	public int addDataListener(int dataConnectionId, IDataProcessor dataProcessor) {
400
	public int addDataListener(int dataConnectionId, IDataProcessor dataProcessor)
422
		if(dataConnectionId == -1) return -1;
401
	{
423
		
402
		if(dataConnectionId == -1){ return -1;}
403
		DataConnection dataConnectionInfo = (DataConnection)_dataConnectionMap.get(new Integer(dataConnectionId));
424
		DataConnection dataConnectionInfo = (DataConnection)_dataConnectionMap.get(new Integer(dataConnectionId));
404
		ACTCPDataServer dataServer = dataConnectionInfo.getDataServer();
425
		ACTCPDataServer dataServer = dataConnectionInfo.getDataServer();
405
		if(dataServer != null)
426
		if(dataServer != null) { 
406
		{ 
407
			dataServer.addDataprocessor(dataProcessor);
427
			dataServer.addDataprocessor(dataProcessor);
408
			return 0;
428
			return 0;
409
		}
429
		}
430
		
410
		return -1;
431
		return -1;
411
	}
432
	}
412
	
433
	
413
	public int removeDataListener(int dataConnectionId, IDataProcessor dataProcessor)
434
	public int removeDataListener(int dataConnectionId, IDataProcessor dataProcessor) {
414
	{
435
		try	{
415
		try
416
		{
417
			DataConnection dataConnectionInfo = (DataConnection)_dataConnectionMap.get(new Integer(dataConnectionId));
436
			DataConnection dataConnectionInfo = (DataConnection)_dataConnectionMap.get(new Integer(dataConnectionId));
418
			ACTCPDataServer dataServer = dataConnectionInfo.getDataServer();
437
			ACTCPDataServer dataServer = dataConnectionInfo.getDataServer();
419
			dataServer.removeDataprocessor(dataProcessor);
438
			dataServer.removeDataprocessor(dataProcessor);
420
			dataServer.shutdownServer();
439
			dataServer.shutdownServer();
421
		}catch(Exception e)
440
		} catch(Exception e) {}
422
		{
441
		
423
			///e.printStackTrace();
424
		}
425
		return 0;
442
		return 0;
426
	}	
443
	}	
427
	
444
	
Lines 435-448 Link Here
435
		_dataConnectionMap.remove(new Integer(dataConnID));
452
		_dataConnectionMap.remove(new Integer(dataConnID));
436
	}
453
	}
437
	
454
	
438
	private void closeDataConnection(int dataConnID)
455
	private void closeDataConnection(int dataConnID) {
439
	{
440
		DataConnection dataConnectionInfo = (DataConnection)_dataConnectionMap.get(new Integer(dataConnID));
456
		DataConnection dataConnectionInfo = (DataConnection)_dataConnectionMap.get(new Integer(dataConnID));
441
		
457
		
442
		try
458
		try {
443
		{
459
			if (dataConnectionInfo != null) {
444
			if (dataConnectionInfo != null)
445
			{
446
				// Send DISCONNECT command for data channel
460
				// Send DISCONNECT command for data channel
447
				sendControlCommand(Constants.DISCONNECT); 
461
				sendControlCommand(Constants.DISCONNECT); 
448
	
462
	
Lines 452-522 Link Here
452
				dataConnectionInfo.getDataSocket().close();
466
				dataConnectionInfo.getDataSocket().close();
453
			}
467
			}
454
		}
468
		}
455
		catch(Exception exp)
469
		catch(Exception exp) {
456
		{
457
			if (Constants.TPTP_DEBUG) System.out.println("Error destroying the data channel - " + exp.getMessage());
470
			if (Constants.TPTP_DEBUG) System.out.println("Error destroying the data channel - " + exp.getMessage());
458
		}	
471
		}	
459
	}
472
	}
460
	
473
	
461
	public void sendData(int dataConnectionId, byte[] buffer, int bufferLength)
474
	public void sendData(int dataConnectionId, byte[] buffer, int bufferLength) {
462
	{
475
		try {
463
		try
464
		{
465
			DataConnection dataConnectionInfo = (DataConnection)_dataConnectionMap.get(new Integer(dataConnectionId));
476
			DataConnection dataConnectionInfo = (DataConnection)_dataConnectionMap.get(new Integer(dataConnectionId));
466
			OutputStream stream=dataConnectionInfo._dataSocket.getOutputStream();
477
467
			stream.write(buffer);
478
			synchronized (writeDataLock) {
468
			stream.flush();
479
				OutputStream stream=dataConnectionInfo._dataSocket.getOutputStream();
469
		}
480
				stream.write(buffer);
470
		catch(IOException exp)
481
				stream.flush();
471
		{
482
			}
472
			System.out.println("Error writing the data to the Socket - " + exp);
483
		}
473
		}
484
		catch(IOException exp) {
474
		catch(Exception e)
485
		}
475
		{
486
		catch(Exception e) {
476
			System.out.println("Error sending the data - " + e);
477
		}			
487
		}			
478
	}
488
	}
479
489
480
	public void sendMessage(IControlMessage msg, ICommandHandler handler) throws IOException 
490
	public void sendMessage(IControlMessage msg, ICommandHandler handler) throws IOException {
481
	{
491
		try	{
482
		int commandCount = msg.getCommandCount();
492
			if (handler != null) {
483
493
				int commandCount = msg.getCommandCount();
484
		try
494
				for (int i=0; i < commandCount; i++) {
485
		{
495
					_contextMapper.addContext(msg.getCommand(i).getContext(), handler);
486
			for (int i=0; i < commandCount; i++) {
496
				}
487
				//System.out.println("Adding the handler to the context ...");
488
				//System.out.println("Context:" + msg.getCommand(i).getContext());
489
				//System.out.println("Handler:" + handler);
490
			    this._contextMapper.addContext(msg.getCommand(i).getContext(), handler);
491
			}
497
			}
492
			
498
			
493
			int count=msg.getSize();
499
			byte[] buffer=new byte[msg.getSize()];
494
			//System.out.println("message size " + count);
495
			byte[] buffer=new byte[count];
496
			msg.writeToBuffer(buffer, 0);
500
			msg.writeToBuffer(buffer, 0);
497
	
501
	
498
			OutputStream stream=_socket.getOutputStream();
502
			synchronized (writeLock) {
499
			stream.write(buffer);
503
				OutputStream stream=_socket.getOutputStream();
500
			stream.flush();
504
				stream.write(buffer);
505
				stream.flush();
506
			}
501
		}
507
		}
502
		catch(IOException exp)
508
		catch(IOException exp) {
503
		{
504
			if (Constants.TPTP_DEBUG)System.out.println("SendMessage error - " + exp);
509
			if (Constants.TPTP_DEBUG)System.out.println("SendMessage error - " + exp);
505
			throw exp;
510
			throw exp;
506
		}
511
		}
507
		catch(Exception exp)
512
		catch(Exception exp) {
508
		{
509
			if (Constants.TPTP_DEBUG)System.out.println("SendMessage error - " + exp);
513
			if (Constants.TPTP_DEBUG)System.out.println("SendMessage error - " + exp);
510
			//throw exp;
511
		}
514
		}
512
513
	}
515
	}
514
516
515
	public void disconnect() {
517
	public void disconnect() {
516
		synchronized(_connectionLock) {
517
			if(!_isComplete) {
518
			if(!_isComplete) {
518
				_isComplete=true;
519
				_isComplete=true;
519
				_connectionLock.notifyAll();
520
520
				try 
521
				try 
521
				{
522
				{
522
					// Destroy Data Connections
523
					// Destroy Data Connections
Lines 533-543 Link Here
533
					// Send DISCONNECT command
534
					// Send DISCONNECT command
534
					sendControlCommand(Constants.DISCONNECT);
535
					sendControlCommand(Constants.DISCONNECT);
535
					
536
					
536
					// Close the SocketReaderThread
537
					_isComplete = true;
538
					
539
					// Close the Socket
540
					_socket.close();
541
					if (Constants.TPTP_DEBUG) System.out.println("Successfully disconnected.");
537
					if (Constants.TPTP_DEBUG) System.out.println("Successfully disconnected.");
542
				}
538
				}
543
				catch(IOException e) {
539
				catch(IOException e) {
Lines 545-550 Link Here
545
					if (Constants.TPTP_DEBUG) System.out.println("Exception while disconnecting ... " + e);
541
					if (Constants.TPTP_DEBUG) System.out.println("Exception while disconnecting ... " + e);
546
				}
542
				}
547
				
543
				
544
				close();
545
548
				/* If this is a nodeimpl clear the keystore spec so it tries an insecure connect next time */
546
				/* If this is a nodeimpl clear the keystore spec so it tries an insecure connect next time */
549
				//Commented by GN since security not supported yet in the new 
547
				//Commented by GN since security not supported yet in the new 
550
				//	if(_node instanceof INode) {
548
				//	if(_node instanceof INode) {
Lines 562-570 Link Here
562
				}
560
				}
563
				*/			
561
				*/			
564
			}
562
			}
565
		}
566
	}
563
	}
567
564
565
	public void close () {
566
		if (_socket != null) {
567
			try { 
568
				_socket.close(); 
569
			} catch (Exception e) {}
570
		}
571
		
572
		_isComplete = true;
573
	}
574
	
568
	public INode getNode() {
575
	public INode getNode() {
569
		return _node;
576
		return _node;
570
	}
577
	}
Lines 575-586 Link Here
575
		}
582
		}
576
		return false;
583
		return false;
577
	}
584
	}
578
	public static int checkForRACMessage(byte[] buffer, int offset)
585
	
579
	{
586
	public static int checkForRACMessage(byte[] buffer, int offset) {
580
		Message tempMessage=new Message();
587
		Message tempMessage=new Message();
581
		tempMessage.readFromBuffer(buffer, offset);
588
		tempMessage.readFromBuffer(buffer, offset);
582
		if(tempMessage.getMagicNumber() == Constants.RA_MAGIC)
589
		if(tempMessage.getMagicNumber() == Constants.RA_MAGIC) {
583
		{
584
			return Constants.RAC_MESSAGE_HEADER_SIZE;
590
			return Constants.RAC_MESSAGE_HEADER_SIZE;
585
		} 
591
		} 
586
		return -1;
592
		return -1;
Lines 589-705 Link Here
589
	public int getPort() {
595
	public int getPort() {
590
		return _port;
596
		return _port;
591
	}
597
	}
598
	
599
	public InetAddress getInetAddress() {
600
		return inetAddress;
601
	}
602
	
592
	protected ContextMapper getContextMapper()
603
	protected ContextMapper getContextMapper()
593
	{
604
	{
594
	    return this._contextMapper;
605
	    return this._contextMapper;
595
	}
606
	}
596
607
597
	protected int processControlMessage(byte[] buffer, int offset, int length) {
608
	protected int processControlMessage(byte[] buffer, int offset, int length) {
598
		if(_cmdHandler != null) {
609
		if(_cmdHandler == null) return -1;
599
			ControlMessage msg=new ControlMessage();
610
		
600
			msg.setMessageType(Constants.TPTP_AC_MESSAGE);
611
		ControlMessage msg=new ControlMessage();
612
		msg.setMessageType(Constants.TPTP_AC_MESSAGE);
601
613
602
			int current=-1;
614
		int current=-1;
603
			try {
615
		try {
604
				if(Constants.TPTP_DEBUG)System.out.println("Processing the Message.");
616
			if(Constants.TPTP_DEBUG)System.out.println("Processing the Message.");
605
				if (buffer.length == length + offset) {
617
			if (buffer.length == length + offset) {
606
					current = msg.readFromBuffer(buffer, offset);
618
				current = msg.readFromBuffer(buffer, offset);
607
				}
619
			}
608
				else {
620
			else {
609
					// length is not passed to readFromBuffer so we should ensure 
621
				// length is not passed to readFromBuffer so we should ensure 
610
					// that readFromBuffer will not read trash from the end of the buffer
622
				// that readFromBuffer will not read trash from the end of the buffer
611
					// and no exception will be thrown.
623
				// and no exception will be thrown.
612
					// ControlMessage.readFromBuffer(buffer, offset, length) method
624
				// ControlMessage.readFromBuffer(buffer, offset, length) method
613
					// is needed in order to prevent extra memory allocations in this case.
625
				// is needed in order to prevent extra memory allocations in this case.
614
					byte[] buffer2 = new byte[length];
626
				byte[] buffer2 = new byte[length];
615
					System.arraycopy(buffer, offset, buffer2, 0, length);
627
				System.arraycopy(buffer, offset, buffer2, 0, length);
616
					current = msg.readFromBuffer(buffer2, 0);
628
				current = msg.readFromBuffer(buffer2, 0);
617
					if (current >= 0)
629
				if (current >= 0)
618
						current += offset;
630
					current += offset;
619
				}
620
				/* If we read more bytes then were valid, return -1 */
621
				if(current>offset+length) 
622
				{
623
					return -1;
624
				}
625
			}
631
			}
626
			catch(IndexOutOfBoundsException e) 
632
			/* If we read more bytes then were valid, return -1 */
627
			{  
633
			if(current>offset+length) {
628
				return -1;
634
				return -1;
629
			}
635
			}
630
			catch(Exception e) 
636
		}
631
			{
637
		catch(IndexOutOfBoundsException e) {  
632
		    	System.out.println("Exception while processing the message" + e);
638
			return -1;
633
		            return -1;
639
		}
634
			}
640
		catch(Exception e) {
641
			System.out.println("Exception while processing the message" + e);
642
	        return -1;
643
		}
635
644
636
	         /* If we have parsed the message successfully  Then process it */
645
	        /* If we have parsed the message successfully  Then process it */
637
			int len = msg.getSize();
646
		int len = msg.getSize();
638
			
647
			
639
		    if (current == len+offset) {
648
	    if (current == len+offset) {
640
				/* Valid pass on each command */
649
			/* Valid pass on each command */
641
	    		if(Constants.TPTP_DEBUG)System.out.println("Checking for CONNECTION_COMPLETE response");
650
//	    		if(Constants.TPTP_DEBUG)System.out.println("Checking for CONNECTION_COMPLETE response");
642
	    		long flags = msg.getFlags();
651
	   		long flags = msg.getFlags();
643
		    	if ((flags & Constants.CONNECTION_COMPLETE) != 0)
652
   			
644
		    	{			    		
653
	   		if ((flags & Constants.AUTHENTICATION_FAILED) != 0) {
645
		    		this._connectionId = extractConnectionId(buffer, current);
654
	   			isAuthenticated = false;
646
		    		current += msg.getLength();
655
	   			synchronized (authLock) {
647
		    		if(Constants.TPTP_DEBUG)System.out.println("Connection complete response - " + _connectionId);
656
	   				authLock.notifyAll();
648
		    		synchronized (_connectionLock) {
657
	   			}
649
		    			_connectionLock.notifyAll();
658
	   		}
650
		    		}
659
    		else if ((flags & Constants.AUTHENTICATION_SUCCESSFUL) != 0) {
651
		    	}
660
    			isAuthenticated = true;
652
		    	if((flags & Constants.CONNECTION_RECONNECT_REQUEST) !=  0)
661
	   			synchronized (authLock) {
653
				{ 
662
	   				authLock.notifyAll();
654
    	 			int portreq = -1;
663
	   			}
655
	    			synchronized(_socket)
664
    		}
656
	    			{	
665
	    	else {
657
			    		try
666
	    		int count=msg.getCommandCount();
658
			    		{
667
	    		for(int i=0; i<count; i++) {
659
				    		_isComplete=true;
668
	    			_cmdHandler.incomingCommand(_node, msg.getCommand(i));
660
				    		_dataConnectionMap.clear();
669
	    		}
661
		    				_socket.close();
670
	    	}
662
		    				CommandFragment cmd=(CommandFragment)msg.getCommand(0);
671
	   	}
663
		    				String strToParse = cmd.getCommandData();//new String(buffer,Constants.ACK_HDR_LEN,buffer.length-12);
664
		    				TPTPXMLParse ParseObj = new TPTPXMLParse();
665
		    	 			ParseObj.setParser(strToParse.trim());
666
		    	 			Hashtable CommandHash = ParseObj.getHashTable();
667
		    	 			if(CommandHash.containsKey("port"))
668
		    	 			{
669
		    	 				portreq = Integer.parseInt((String)ParseObj.getHashTable().get("port"));
670
		    	 			}
671
			    		}
672
				    	catch(Exception e){}
673
		    		}
674
		    	 			
675
    				if(portreq == -1) {
676
    					// This is a bad situation.  The AC should have given us a port
677
    					// Since it didn't (unexpectedly), let's try a default
678
    					portreq = 10006;
679
    				}
680
    				
681
    				// Tell the caller how to reconnect
682
					_reconnectRequestedException = new ReconnectRequestedException( portreq );
683
					synchronized (_connectionLock) {
684
						// This notify will cause init to throw the above request
685
						// and cause the read thread to bail
686
						_connectionLock.notifyAll();
687
					}
688
		    	}
689
				int count=msg.getCommandCount();
690
672
691
				for(int i=0; i<count; i++) 
673
	    return current; 
692
				{
693
					_cmdHandler.incomingCommand(_node, msg.getCommand(i));
694
				}
695
			}
696
			return current;
697
		}
698
		return -1;
699
	}
674
	}
700
	
675
	
701
	
702
	
703
	/**
676
	/**
704
	 * @see Connection#addConnectionListener(ConnectionListener)
677
	 * @see Connection#addConnectionListener(ConnectionListener)
705
	 */
678
	 */
Lines 710-716 Link Here
710
			}
683
			}
711
		}
684
		}
712
	}
685
	}
713
714
	
686
	
715
	/**
687
	/**
716
	 * @see Connection#removeConnectionListener(ConnectionListener)
688
	 * @see Connection#removeConnectionListener(ConnectionListener)
Lines 726-744 Link Here
726
	public void setSoTimeout(int timeout) {
698
	public void setSoTimeout(int timeout) {
727
		_soTimeout = timeout;
699
		_soTimeout = timeout;
728
	}
700
	}
701
	
702
	public Socket getSocket() {
703
		return _socket;
704
	}
705
	
706
	public void setSocket(Socket socket) {
707
		_socket = socket;
708
		_isComplete = true; 
709
	}
729
710
730
	class SocketReaderThread extends Thread implements Constants 
711
	class SocketReaderThread extends Thread implements Constants {
731
	{
712
		public void run() {
732
		public void run() 
713
			byte[] buffer = new byte[MAX_MESSAGE_LENGTH];
733
		{
734
			/* Run forever */
735
			byte[] buffer=new byte[MAX_MESSAGE_LENGTH];
736
			int masterOffset=0;
714
			int masterOffset=0;
737
			boolean incompleteMsg;
715
			boolean incompleteMsg;
738
			int timeoutCount=0;
716
739
			_isComplete = false;
717
			_isComplete = false;
740
			
718
			
741
			/* Get the InputStream for this socket so we can read some data */
719
			// Get the InputStream for this socket so we can read some data 
742
			BufferedInputStream inStream;
720
			BufferedInputStream inStream;
743
			try {
721
			try {
744
				inStream = new BufferedInputStream(_socket.getInputStream());
722
				inStream = new BufferedInputStream(_socket.getInputStream());
Lines 749-819 Link Here
749
				return;
727
				return;
750
			}
728
			}
751
729
752
			while(!_isComplete) 
730
			while(!_isComplete) {
753
			{
731
				incompleteMsg = false;  // 185463 
754
				incompleteMsg = false;  /* 185463 */
732
				try	{
755
				try 
733
					int bytesRead = inStream.read(buffer, masterOffset, buffer.length-masterOffset);
756
				{
734
					if(bytesRead == -1) break;
757
					int bytesRead=inStream.read(buffer, masterOffset, buffer.length-masterOffset);
758
					
735
					
759
					if(bytesRead==-1) {break;}
736
			        if (masterOffset > 0) {
760
					
761
			        if (masterOffset > 0) 
762
			        {
763
			        	bytesRead += masterOffset;
737
			        	bytesRead += masterOffset;
764
						masterOffset = 0;
738
						masterOffset = 0;
765
			        }
739
			        }
766
			      
740
			      
767
					/*
741
					//
768
					 * If we've tried to connect to a backward compatibility
742
					// If we've tried to connect to a backward compatibility
769
					 * layer of the AC, we'll immediately get a response in 
743
					// layer of the AC, we'll immediately get a response in 
770
					 * RAC format.  If we ignore this, the BC layer will
744
					// RAC format.  If we ignore this, the BC layer will
771
					 * respond to our first message by giving us the port
745
					// respond to our first message by giving us the port
772
					 * to connect to the regular socket TL.
746
					// to connect to the regular socket TL.
773
					 */
747
					//
774
					int vret = checkForRACMessage(buffer, masterOffset);
748
					int vret = checkForRACMessage(buffer, masterOffset);
775
					if(vret != -1)
749
					if (vret != -1) {
776
					{
777
						// We read the header, the next four bytes will be the length 
750
						// We read the header, the next four bytes will be the length 
778
						// (including the header) of the RAC message
751
						// (including the header) of the RAC message
779
						long length=TPTPMessageUtil.readTPTPLongFromBuffer(buffer, vret);
752
						long length = TPTPMessageUtil.readTPTPLongFromBuffer(buffer, vret);
780
						masterOffset = (int)length;
753
						masterOffset = (int)length;
781
					}
754
					}
782
	
755
	
783
					while(masterOffset<bytesRead) 
756
					while(masterOffset<bytesRead) {
784
					{
785
						int newOffset=0;
757
						int newOffset=0;
786
						/* First we make sure we have at least enough read for the message header.
758
						// First we make sure we have at least enough read for the message header.
787
						   If not, compress and re-read.
759
						 //  If not, compress and re-read.
788
						*/
760
						//
789
						if ( bytesRead-masterOffset < AC_MESSAGE_HEADER_SIZE ) {
761
						if ( bytesRead-masterOffset < AC_MESSAGE_HEADER_SIZE ) {
790
							System.arraycopy( buffer, masterOffset, buffer, 0, bytesRead-masterOffset );
762
							System.arraycopy( buffer, masterOffset, buffer, 0, bytesRead-masterOffset );
791
							masterOffset=bytesRead-masterOffset;
763
							masterOffset=bytesRead-masterOffset;
792
							incompleteMsg = true;
764
							incompleteMsg = true;
793
							break;
765
							break;
794
						}
766
						}
795
						/* We have the header information, now lets try and get the entire message.  Once
767
						
796
						   again the same error conditions can occur.
768
						// We have the header information, now lets try and get the entire message.  Once
797
						*/
769
						 //  again the same error conditions can occur.
798
						if(Constants.TPTP_DEBUG)System.out.println("Received a non-acknowledgement message");
770
						//
799
						//System.out.println("Offset xx::"+new String(buffer));
771
						newOffset = processControlMessage(buffer, masterOffset, bytesRead);
800
						newOffset=processControlMessage(buffer, masterOffset, bytesRead);
772
						
801
						if(Constants.TPTP_DEBUG)System.out.println("Recvd Message : " + buffer.toString());
773
						if(Constants.TPTP_DEBUG)System.out.println("Recvd Message: " + buffer.toString());
802
						if ( newOffset == -1 ) 
774
						
803
						{
775
						if (newOffset == -1) {
804
							// newOffset of -1 indicates the message is bigger than what's left in the buffer
776
							// newOffset of -1 indicates the message is bigger than what's left in the buffer
805
							// If the masterOffset is zero, this means the message is bigger than the buffer 
777
							// If the masterOffset is zero, this means the message is bigger than the buffer 
806
							//   itself, so we need to grow the buffer.  Otherwise, we'll slide the message
778
							//   itself, so we need to grow the buffer.  Otherwise, we'll slide the message
807
							//   to the beginning of the buffer and try to read some more
779
							//   to the beginning of the buffer and try to read some more
808
							if(masterOffset>0) 
780
							if(masterOffset>0) {
809
							{
810
								System.arraycopy( buffer, masterOffset, buffer, 0, bytesRead-masterOffset );
781
								System.arraycopy( buffer, masterOffset, buffer, 0, bytesRead-masterOffset );
811
							}
782
							}
812
		 					else if (bytesRead == buffer.length) 
783
		 					else if (bytesRead == buffer.length) 
813
         					{
784
         					{
814
		                        int len = buffer.length * 2;
785
		                        int len = buffer.length * 2;
815
		                        byte[] tmpbuffer=new byte[len];
786
		                        byte[] tmpbuffer=new byte[len];
816
		                        /* Copy necessary data over to new buffer */
787
		                        // Copy necessary data over to new buffer 
817
		                        System.arraycopy(buffer, masterOffset, tmpbuffer, 0, bytesRead-masterOffset);
788
		                        System.arraycopy(buffer, masterOffset, tmpbuffer, 0, bytesRead-masterOffset);
818
		                        buffer = tmpbuffer;
789
		                        buffer = tmpbuffer;
819
                 			}
790
                 			}
Lines 822-843 Link Here
822
							break;
793
							break;
823
						}
794
						}
824
						masterOffset=newOffset;
795
						masterOffset=newOffset;
825
					} /* end of inner while */
796
					} // end of inner while 
826
	
797
	
827
					if (!incompleteMsg) 
798
					if (!incompleteMsg) 
828
					{
799
					{
829
						masterOffset=0;
800
						masterOffset=0;
830
				    }
801
				    }
831
				}
802
				}
832
				catch(InterruptedIOException e) 
803
				catch(InterruptedIOException e) {
833
				{
834
					 if(timeoutCount > Constants.CONNECT_TIMEOUT_TRY_COUNT && !_isInitialized) 
835
					 {
836
						 synchronized(_connectionLock) {
837
					 		_connectionLock.notifyAll();
838
					 	}
839
					 }
840
					 timeoutCount++;
841
				}
804
				}
842
				catch(SocketException e) 
805
				catch(SocketException e) 
843
				{
806
				{
Lines 849-857 Link Here
849
					//e.printStackTrace();
812
					//e.printStackTrace();
850
					break;
813
					break;
851
				}
814
				}
852
			} /* end of outer while */
815
			} // end of outer while 
853
			/* The server is now stopping */
816
			// The server is now stopping 
817
			
854
			disconnect();
818
			disconnect();
855
		}
819
		}
856
	}
820
	}
821
	
822
	public boolean isAuthenticated() {
823
		return isAuthenticated;
824
	}
825
	
826
	protected boolean authenticateUser(User user) {
827
		if (user == null || user.getName() == null || user.getPassword() == null) return false;
828
		
829
		ControlMessage authMsg = new ControlMessage();
830
		authMsg.setMessageType(Constants.TPTP_AC_MESSAGE);
831
		authMsg.setMagicNumber(Constants.AC_MAGIC_NUMBER);
832
		authMsg.setFlags(Constants.AUTHENTICATE);
833
		
834
		AuthenticateCommand authCmd = new AuthenticateCommand(user.getName(), user.getPassword());
835
		authMsg.appendCommand(authCmd);
836
		
837
		try { 
838
			sendMessage(authMsg, new ICommandHandler() {
839
				public void incomingCommand(INode node, ICommandElement command) {}
840
			});
841
		} catch (Exception e) {
842
			return false;
843
		}
844
845
		synchronized (authLock) {
846
			try { authLock.wait(Constants.WAIT_RESPONCE_TIMEOUT); } catch (Exception e) {}
847
		}
848
		
849
		return isAuthenticated;
850
	}
857
}
851
}
(-)src/org/eclipse/tptp/platform/execution/exceptions/LoginFailedException.java (+4 lines)
Lines 28-33 Link Here
28
	private long _port;
28
	private long _port;
29
29
30
30
31
	public LoginFailedException() {
32
		_port = 0;
33
	}
34
31
	public LoginFailedException(long port) {
35
	public LoginFailedException(long port) {
32
		_port=port;
36
		_port=port;
33
	}
37
	}
(-)src/org/eclipse/tptp/platform/execution/client/core/IAgentController.java (+2 lines)
Lines 283-288 Link Here
283
	 */
283
	 */
284
	boolean authenticateUser(User user) throws NotConnectedException;
284
	boolean authenticateUser(User user) throws NotConnectedException;
285
     
285
     
286
	boolean isAuthenticated();
287
	
286
	/**
288
	/**
287
	 * Get a Agent Reference to communicate with the agent
289
	 * Get a Agent Reference to communicate with the agent
288
	 * @param agentName
290
	 * @param agentName
(-)src/org/eclipse/tptp/platform/execution/client/core/NodeFactory.java (-10 / +5 lines)
Lines 87-94 Link Here
87
	 * if the Node exists it will be returned.
87
	 * if the Node exists it will be returned.
88
	 */
88
	 */
89
	public static INode createNode(InetAddress address) throws UnknownHostException {
89
	public static INode createNode(InetAddress address) throws UnknownHostException {
90
		//return createNode(address, null);
90
		String hostname = address.getHostName();
91
		return createNode(address);
91
		INode node = containsNode(hostname);
92
		if (node != null) return node;
93
		
94
		return addNode(hostname, address, null);
92
	}
95
	}
93
96
94
97
Lines 148-157 Link Here
148
		}
151
		}
149
	}
152
	}
150
	
153
	
151
152
153
154
	
155
	private static INode containsNode(String name) {
154
	private static INode containsNode(String name) {
156
		synchronized(_servers) {
155
		synchronized(_servers) {
157
			// If this is "localhost" try and resolve its real name first
156
			// If this is "localhost" try and resolve its real name first
Lines 199-205 Link Here
199
		return null;
198
		return null;
200
	}
199
	}
201
200
202
	
203
	/**
201
	/**
204
	 * Searches the Node list based upon the InetAddress.
202
	 * Searches the Node list based upon the InetAddress.
205
	 * @return the Node if it exists, null otherwise.
203
	 * @return the Node if it exists, null otherwise.
Lines 208-214 Link Here
208
		//return getNode(addr, null);
206
		//return getNode(addr, null);
209
		return containsNode(addr.getHostName());
207
		return containsNode(addr.getHostName());
210
	}
208
	}
211
212
213
}
209
}
214
(-)src/org/eclipse/tptp/platform/execution/client/core/internal/X509TrustManagerImpl.java (+47 lines)
Added Link Here
1
package org.eclipse.tptp.platform.execution.client.core.internal;
2
3
import java.security.KeyStore;
4
import java.security.cert.CertificateException;
5
import java.security.cert.X509Certificate;
6
7
import javax.net.ssl.TrustManager;
8
import javax.net.ssl.TrustManagerFactory;
9
import javax.net.ssl.X509TrustManager;
10
11
public class X509TrustManagerImpl implements X509TrustManager {
12
	private X509TrustManager defaultX509tm; 
13
	
14
	X509TrustManagerImpl () throws Exception {
15
		TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
16
		tmf.init((KeyStore) null);
17
		
18
		TrustManager tms[] = tmf.getTrustManagers();
19
		for (int i=0; i<tms.length; i++) {
20
			if (tms[i] instanceof X509TrustManager) {
21
				defaultX509tm = (X509TrustManager) tms[i];
22
				break;
23
			}
24
		}
25
	}
26
	
27
	public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
28
		if (defaultX509tm == null) throw new CertificateException ("Trust manager not found");
29
		
30
		defaultX509tm.checkClientTrusted(certs, authType);
31
	}
32
33
	public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
34
		if (defaultX509tm != null)
35
			try {
36
				defaultX509tm.checkServerTrusted(certs, authType);
37
				return;
38
			} catch (Exception e) {}
39
			
40
// ask user if certificate is trusted, save it
41
	}
42
43
	public X509Certificate[] getAcceptedIssuers() {
44
		if (defaultX509tm != null) return defaultX509tm.getAcceptedIssuers();
45
		return null;
46
	}
47
}
(-)src/org/eclipse/tptp/platform/execution/client/core/internal/commands/AuthenticateCommand.java (+28 lines)
Added Link Here
1
package org.eclipse.tptp.platform.execution.client.core.internal.commands;
2
3
import org.eclipse.tptp.platform.execution.util.internal.CommandElement;
4
import org.eclipse.tptp.platform.execution.util.internal.TPTPMessageUtil;
5
import org.eclipse.tptp.platform.execution.util.internal.TPTPString;
6
7
public class AuthenticateCommand extends CommandElement {
8
	private TPTPString name;
9
	private TPTPString password;
10
	
11
	public AuthenticateCommand(String name, String password) {
12
		this.name = new TPTPString(name);
13
		this.password = new TPTPString(password);
14
	}
15
	
16
	public int getSize() {
17
		return name.getSize() + password.getSize();
18
	}
19
20
	public int readFromBuffer(byte[] buffer, int offset) {
21
		return 0;
22
	}
23
24
	public int writeToBuffer(byte[] buffer, int offset) {
25
		int current = TPTPMessageUtil.writeTPTPStringToBuffer(buffer, offset, name);
26
		return TPTPMessageUtil.writeTPTPStringToBuffer(buffer, current, password);
27
	}
28
}
(-)src/org/eclipse/tptp/platform/execution/client/core/internal/ConnectionFactory.java (+39 lines)
Added Link Here
1
package org.eclipse.tptp.platform.execution.client.core.internal;
2
3
import java.io.IOException;
4
5
import org.eclipse.tptp.platform.execution.client.core.ConnectionInfo;
6
import org.eclipse.tptp.platform.execution.client.core.INode;
7
import org.eclipse.tptp.platform.execution.exceptions.LoginFailedException;
8
import org.eclipse.tptp.platform.execution.exceptions.NotConnectedException;
9
import org.eclipse.tptp.platform.execution.exceptions.ReconnectRequestedException;
10
import org.eclipse.tptp.platform.execution.exceptions.SecureConnectionRequiredException;
11
import org.eclipse.tptp.platform.execution.exceptions.UntrustedAgentControllerException;
12
13
public class ConnectionFactory {
14
	public static IConnection createConnection (INode node, ConnectionInfo conInfo) throws LoginFailedException, 
15
		UntrustedAgentControllerException, IOException, ReconnectRequestedException, SecureConnectionRequiredException,
16
		NotConnectedException {
17
		
18
		ConnectionImpl con = null;
19
		boolean securityRequired = false;
20
21
		try {
22
			con = new ConnectionImpl();
23
			con.connect(node, conInfo);
24
		} catch (SecureConnectionRequiredException e) {
25
			securityRequired = true;
26
		}
27
	
28
		if (!securityRequired) return con;	// insecure connection
29
		
30
		SecureConnectionImpl secCon = new SecureConnectionImpl ();
31
			
32
		if (!secCon.connect(node, con)) {
33
			secCon.close();
34
			secCon = null;
35
		}
36
			
37
		return secCon;
38
	}
39
}
(-)src/org/eclipse/tptp/platform/execution/samples/SecureClientAC.java (+116 lines)
Added Link Here
1
package org.eclipse.tptp.platform.execution.samples;
2
3
import org.eclipse.tptp.platform.execution.client.agent.*;
4
import org.eclipse.tptp.platform.execution.client.core.*;
5
import org.eclipse.tptp.platform.execution.security.User;
6
import org.eclipse.tptp.platform.execution.util.*;
7
8
public class SecureClientAC {
9
	public final static String HOST = "localhost";
10
	public final static int PORT = 10006;
11
	
12
	public static void main(String[] args) {
13
		ConnectionInfo connInfo = null;
14
		IAgentController ac = null;
15
		INode node = null;
16
17
		System.out.println("Connecting to Agent Controller\n");
18
19
		try {
20
			node = NodeFactory.createNode(HOST);
21
			//Set the connection parameters required 
22
			connInfo = new ConnectionInfo();
23
			connInfo.setHostName(HOST);
24
			connInfo.setPort(PORT);
25
26
			ac = node.connect(connInfo);
27
		} catch (Exception e) {
28
			System.out.println("Error occurred while connecting to " + HOST + ":" + e);
29
		}
30
31
		if (ac == null) return;
32
33
		System.out.println("Connected to " + HOST + ":" + PORT);
34
		
35
		while (!ac.isAuthenticated()) {
36
			User user = getUser();
37
			if (user == null) {
38
				System.out.println("\nAuthentication failed");
39
				break;
40
			}
41
			
42
			try {
43
				ac = node.connect(connInfo, user);
44
			} catch (Exception e) {}
45
		}
46
47
		if (!ac.isAuthenticated()) {
48
			ac.disconnect();
49
			return;
50
		}
51
		
52
		try {
53
			ICollector timeCollector = (ICollector) ac.getAgent("org.eclipse.tptp.TimeCollector", "org.eclipse.tptp.platform.execution.client.agent.ICollector");
54
			if(timeCollector == null) {
55
				System.out.println("Agent not available, configure the agent and retry");
56
				ac.disconnect();
57
				return;
58
			}
59
				
60
			//Create the Data Connection required to recieve response from the collector;
61
			//The input to startMonitoring is the to establish the data connection between the client and 
62
			//the agent controller for the direction of data flow.
63
			//See constants for additional values.
64
			timeCollector.startMonitoring(TPTPDataPath.DATA_PATH_TWO_WAY);
65
			timeCollector.addDataListener(new IDataProcessor() {
66
				public void incomingData(byte[] buffer, int length, java.net.InetAddress peer) {
67
					String data = new String(buffer, 0, length);
68
					System.out.println("The Data received from TimeCollector - " + data.trim());
69
				}
70
							
71
				public void incomingData(char[] buffer, int length, java.net.InetAddress peer) {}
72
				public void invalidDataType(byte[] data, int length, java.net.InetAddress peer) {}
73
				public void waitingForData() {}
74
			});				
75
				
76
			//Send a message to Agent
77
				
78
			timeCollector.run();
79
			timeCollector.sendData("HELLO from org.eclipse.tptp.platform.execution plugin".getBytes());
80
				//Wait for the response to arrive
81
				Thread.sleep(2000);
82
				
83
			timeCollector.stop();
84
			
85
			Thread.sleep(1000); 
86
				// Disconnect from AC				
87
			ac.disconnect();
88
			System.out.println("disconnected");				
89
		}
90
		catch(Exception exp) {
91
			System.out.println("Error occurred while connecting to " + HOST + ":" + exp);
92
		}		
93
	}
94
	
95
	private static User getUser() {
96
		byte buf[] = new byte[256];
97
		int n;
98
		
99
		System.out.println("\nUser authentication.");
100
		System.out.print("Login: ");
101
		try { n = System.in.read(buf); } catch (Exception e) { n = 0; }
102
		if (n <= 0) return null;
103
104
		String login = new String(buf, 0, n).trim();
105
		if (login.length() == 0) return null;
106
		
107
		System.out.print("Password: ");
108
		try { n = System.in.read(buf); } catch (Exception e) { n = 0; }
109
		if (n <= 0) return null;
110
		
111
		String psw = new String(buf, 0, n).trim();
112
		if (psw.length() == 0) return null;
113
114
		return new User(null, login, psw);
115
	}
116
}

Return to bug 195644