1 package com.sslexplorer.agent; 2 3 import java.io.IOException ; 4 import java.io.InputStream ; 5 import java.io.OutputStream ; 6 import java.lang.reflect.Field ; 7 import java.lang.reflect.Method ; 8 import java.util.HashMap ; 9 import java.util.Timer ; 10 import java.util.TimerTask ; 11 12 import org.apache.commons.logging.Log; 13 import org.apache.commons.logging.LogFactory; 14 15 import com.maverick.multiplex.Channel; 16 import com.maverick.multiplex.ChannelFactory; 17 import com.maverick.multiplex.MultiplexedConnection; 18 import com.maverick.multiplex.Request; 19 import com.maverick.multiplex.RequestHandler; 20 import com.maverick.multiplex.TimeoutCallback; 21 import com.maverick.util.ByteArrayWriter; 22 import com.sslexplorer.boot.RequestHandlerTunnel; 23 import com.sslexplorer.boot.VersionInfo; 24 import com.sslexplorer.properties.Property; 25 import com.sslexplorer.properties.impl.profile.ProfilePropertyKey; 26 import com.sslexplorer.security.LogonControllerFactory; 27 import com.sslexplorer.security.SessionInfo; 28 import com.sslexplorer.security.User; 29 30 public class AgentTunnel extends MultiplexedConnection implements 31 RequestHandlerTunnel, TimeoutCallback { 32 33 static Log log = LogFactory.getLog(AgentTunnel.class); 34 35 38 public static final String UPDATE_RESOURCES_REQUEST = "updateResources@3sp.com"; 39 40 43 public static final String SYNCHRONIZED_REQUEST = "synchronized@3sp.com"; 44 45 MultiplexedConnection con = null; 46 47 String type; 48 49 HashMap properties = new HashMap (); 50 51 String id; 52 53 SessionInfo session; 54 55 SyncHandler syncHandler = new SyncHandler(); 56 57 int timeoutId; 58 public static final int KEEP_ALIVE_TIMEOUT = 10000; 59 60 70 public AgentTunnel(String id, User user, String type, ChannelFactory factory) { 71 this(id, null, user, type, factory); 72 } 73 74 87 public AgentTunnel(String id, SessionInfo session, User user, String type, 88 ChannelFactory factory) { 89 super(factory); 90 this.id = id; 91 this.session = session; 92 this.type = type; 93 registerRequestHandler(AgentTunnel.SYNCHRONIZED_REQUEST, syncHandler); 94 } 95 96 101 public String getId() { 102 return id; 103 } 104 105 public void register() { 106 timeoutId = -1; 107 if (session.getHttpSession() != null) { 108 if (Property.getPropertyBoolean(new ProfilePropertyKey( 109 "client.preventSessionTimeoutIfActive", session))) { 110 timeoutId = LogonControllerFactory.getInstance() 111 .addSessionTimeoutBlock(session.getHttpSession(), 112 "SSL-Explorer Agent"); 113 } 114 } 115 116 } 117 118 public void unregister() { 119 if (!session.isInvalidating() && timeoutId != -1) { 120 LogonControllerFactory.getInstance().removeSessionTimeoutBlock( 121 session.getHttpSession(), timeoutId); 122 } 123 } 124 125 131 public SessionInfo getSession() { 132 return session; 133 } 134 135 public String getType() { 136 return type; 137 } 138 139 public Object getProperty(String name) { 140 return properties.get(name); 141 } 142 143 public void setProperty(String name, Object value) { 144 properties.put(name, value); 145 } 146 147 public void tunnel(InputStream _in, OutputStream _out) { 148 149 if (log.isDebugEnabled()) 150 log.debug("Starting agent tunnel"); 151 152 155 setTimeoutCallback(this); 156 157 startProtocol(_in, _out, false); 158 159 if (log.isDebugEnabled()) 160 log.debug("Stopping agent tunnel"); 161 162 Channel[] channels = getActiveChannels(); 164 for(int i = 0 ; i < channels.length; i++) { 165 channels[i].onChannelClose(); 166 } 167 168 try { 169 AgentManager.getInstance().removeAgent(this); 170 } catch (AgentException e) { 171 log.error("Error removing agent", e); 172 } 173 174 } 175 176 public boolean waitForSync(long ms) throws InterruptedException { 177 synchronized (syncHandler) { 178 if (syncHandler.isSyncCompleted()) { 179 return true; 180 } 181 syncHandler.wait(ms); 182 return syncHandler.isSyncCompleted(); 183 } 184 } 185 186 public class SyncHandler implements RequestHandler { 187 188 private boolean syncCompleted; 189 190 public boolean isSyncCompleted() { 191 return syncCompleted; 192 } 193 194 public synchronized boolean processRequest(Request request, 195 MultiplexedConnection connection) { 196 try { 197 notifyAll(); 198 ByteArrayWriter baw = new ByteArrayWriter(); 199 try { 200 baw.writeString(VersionInfo.getVersion().toString()); 201 request.setRequestData(baw.toByteArray()); 202 return true; 203 } catch (IOException e) { 204 log.error("Failed to send back server version."); 205 return false; 206 } 207 } finally { 208 syncCompleted = true; 209 } 210 } 211 212 public void postReply(MultiplexedConnection connection) { 213 DefaultAgentManager.getInstance().startServices( 214 (AgentTunnel) connection); 215 } 216 } 217 218 public boolean isAlive(MultiplexedConnection con) { 219 224 Thread t = new Thread ("Keep-Alive Thread - " + session.getUser().getPrincipalName() + "," + session.getAddress().getHostAddress()) { 225 public void run() { 226 Request request = new Request("keepAlive@3sp.com"); 227 if(log.isInfoEnabled()) 228 log.info("Socket has timed out! Sending keep-alive to agent"); 229 230 try { 231 sendRequest(request, true, KEEP_ALIVE_TIMEOUT); 232 233 if(log.isInfoEnabled()) 234 log.info("Agent is still alive, continue as normal"); 235 236 } catch (IOException e) { 237 238 if(log.isInfoEnabled()) 239 log.info("Agent did not respond, disconnecting"); 240 241 disconnect("Keep-alive failed"); 242 } 243 } 244 }; 245 t.start(); 246 return true; 247 } 248 } 249 | Popular Tags |