1 package com.sslexplorer.agent.client.tunneling; 2 3 import java.io.IOException ; 4 import java.text.MessageFormat ; 5 import java.util.Enumeration ; 6 import java.util.Hashtable ; 7 8 import com.maverick.multiplex.MultiplexedConnection; 9 import com.maverick.multiplex.Request; 10 import com.maverick.multiplex.RequestHandler; 11 import com.maverick.util.ByteArrayReader; 12 import com.maverick.util.ByteArrayWriter; 13 import com.sslexplorer.agent.client.AbstractResourceManager; 14 import com.sslexplorer.agent.client.Agent; 15 import com.sslexplorer.agent.client.PortMonitor; 16 import com.sslexplorer.agent.client.util.TunnelConfiguration; 17 18 26 public class TunnelManager extends AbstractResourceManager implements RequestHandler, LocalTunnelServerListener { 27 28 static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(TunnelManager.class); 30 32 35 public final static int TUNNEL_RESOURCE_TYPE_ID = 4; 36 37 41 public static final String START_LOCAL_TUNNEL = "startLocalTunnel@3sp.com"; 43 47 public static final String STOP_LOCAL_TUNNEL = "stopLocalTunnel@3sp.com"; 49 52 public static final String START_REMOTE_TUNNEL = "startRemoteTunnel@3sp.com"; 53 54 57 public static final String STOP_REMOTE_TUNNEL = "stopRemoteTunnel@3sp.com"; 58 59 63 public static final String ACTIVE_LOCAL_TUNNELS = "activeLocalTunnels@3sp.com"; 65 69 public static final String CLOSE_LOCAL_TUNNEL = "closeLocalTunnel@3sp.com"; 71 78 public static final String SETUP_AND_LAUNCH_TUNNEL = "setupAndLaunchTunnel@3sp.com"; 80 82 private static int temporaryTunnelId = -1; 83 84 86 87 protected Hashtable activeLocalTunnels = new Hashtable (); 88 89 94 public TunnelManager(Agent agent) { 95 super(agent); 96 agent.getConnection().registerRequestHandler(START_LOCAL_TUNNEL, this); 97 agent.getConnection().registerRequestHandler(STOP_LOCAL_TUNNEL, this); 98 agent.getConnection().registerRequestHandler(START_REMOTE_TUNNEL, this); 99 agent.getConnection().registerRequestHandler(STOP_REMOTE_TUNNEL, this); 100 agent.getConnection().registerRequestHandler(ACTIVE_LOCAL_TUNNELS, this); 101 } 102 103 106 public void getTunnelResources() { 107 super.getResources(TUNNEL_RESOURCE_TYPE_ID, "Tunnels"); 108 } 109 110 115 public void launchResource(int resourceId) { 116 try { 117 ByteArrayWriter baw = new ByteArrayWriter(); 118 baw.writeInt(resourceId); 119 Request request = new Request(SETUP_AND_LAUNCH_TUNNEL, baw.toByteArray()); 120 if (agent.getConnection().sendRequest(request, true)) { 121 log.debug("Tunnel launch setup"); 123 processLaunchRequest(request); 125 } else { 126 log.error("Failed to setup and launch tunnel launch"); 128 } 130 } catch (IOException e) { 131 log.error("Failed to setup and launch tunnel launch", e); 133 } 135 } 136 137 142 public void closeLocalTunnel(int id) { 143 try { 144 ByteArrayWriter baw = new ByteArrayWriter(); 145 baw.writeInt(id); 146 Request request = new Request(CLOSE_LOCAL_TUNNEL, baw.toByteArray()); 147 agent.getConnection().sendRequest(request, false); 148 } catch (IOException e) { 149 log.error("Failed to setup and launch tunnel launch", e); 151 } 153 154 } 155 156 162 public Hashtable getActiveLocalTunnels() { 163 return activeLocalTunnels; 164 } 165 166 172 public boolean processRequest(Request request, MultiplexedConnection con) { 173 log.info("Processing request " + request.getRequestName()); 175 if (request.getRequestName().equals(START_LOCAL_TUNNEL)) { 177 return startLocalTunnel(request.getRequestData()); 178 } else if (request.getRequestName().equals(STOP_LOCAL_TUNNEL)) { 179 stopLocalTunnel(request); 180 return true; 181 } else if (request.getRequestName().equals(ACTIVE_LOCAL_TUNNELS)) { 182 183 try { 184 Hashtable l = getActiveLocalTunnels(); 185 186 ByteArrayWriter msg = new ByteArrayWriter(); 187 msg.writeInt(l.size()); 188 for (Enumeration e = l.keys(); e.hasMoreElements();) { 189 msg.writeInt(((Integer ) e.nextElement()).intValue()); 190 } 191 192 request.setRequestData(msg.toByteArray()); 193 return true; 194 } catch (IOException e) { 195 return false; 196 } 197 198 } else if((request.getRequestName().equals(START_REMOTE_TUNNEL) 199 || request.getRequestName().equals(STOP_REMOTE_TUNNEL)) 200 && request.getRequestData()!=null) { 201 202 203 207 try { 208 ByteArrayReader bar = new ByteArrayReader(request.getRequestData()); 209 int resourceId = (int)bar.readInt(); 210 String resourceName = bar.readString(); 211 String launchId = bar.readString(); 212 String listeningInterface = bar.readString(); 213 int listeningPort = (int) bar.readInt(); 214 String destinationHost = bar.readString(); 215 int destinationPort = (int) bar.readInt(); 216 217 221 222 if (agent.getConfiguration().isDisplayInformationPopups()) { 223 agent.getGUI() 224 .popup(null, 225 MessageFormat.format(Messages.getString( 226 request.getRequestName().equals(START_REMOTE_TUNNEL) ? "TunnelManager.openedRemoteTunnel" : "TunnelManager.closingRemoteTunnel"), new Object [] { 227 listeningInterface, String.valueOf(listeningPort), destinationHost + ":" + destinationPort }), 229 Messages.getString("Agent.title"), "popup-tunnel", -1); } 232 agent.updateInformation(); 233 234 239 PortMonitor portMonitor = agent.getGUI().getPortMonitor(); 240 if(request.getRequestName().equals(START_REMOTE_TUNNEL)) { 241 TunnelConfiguration conf = new DefaultTunnel( 242 resourceId, TunnelConfiguration.REMOTE_TUNNEL, TunnelConfiguration.TCP_TUNNEL, listeningInterface, listeningPort, destinationPort, destinationHost, true, false, resourceName, launchId); 243 RemotePortItem portItem = new RemotePortItem(conf); 244 portMonitor.addPortItem(portItem); 245 } 246 else { 247 int idx = portMonitor.getIndexForId(resourceId); 248 if(idx != -1) { 249 portMonitor.removeItemAt(idx); 250 } 251 } 252 253 return true; 254 } catch (IOException e) { 255 log.error("Failed to process remote tunnel request", e); 257 } 259 260 } 261 262 return false; 263 } 264 265 268 public void postReply(MultiplexedConnection connection) { 269 } 270 271 284 public LocalTunnelServer startTemporaryLocalTunnel(String name, String hostToConnect, String sourceInterface, 285 int portToConnect, boolean usePreferredPort, boolean singleConnection, 286 String launchId) throws IOException { 287 DefaultTunnel t = new DefaultTunnel(getTemporaryTunnelId(), 288 TunnelConfiguration.LOCAL_TUNNEL, 289 TunnelConfiguration.TCP_TUNNEL, 290 sourceInterface, 291 (usePreferredPort ? portToConnect : 0), 292 portToConnect, 293 hostToConnect, 294 false, 295 singleConnection, 296 name, 297 launchId); 298 299 return startLocalTunnel(t); 300 } 301 302 309 public LocalTunnelServer startLocalTunnel(TunnelConfiguration conf) throws IOException { 310 311 if (conf.getType() != TunnelConfiguration.LOCAL_TUNNEL) 312 throw new IOException ("Invalid tunnel type " + conf.getType()); 314 LocalTunnelServer listener = new LocalTunnelServer(agent, agent.getTXIOListener(), agent.getRXIOListener(), conf); 315 listener.addListener(this); 316 listener.start(); 317 return listener; 318 } 319 320 326 public void stopLocalTunnel(int id) { 327 stopLocalTunnel(new Integer (id), true); 328 } 329 330 337 public void localTunnelConnectionDataTransferred(LocalTunnelServer localForwardingServer, LocalTunnelConnection activeTunnel, byte[] buffer, 338 int count, boolean sent) { 339 } 340 341 347 public void localTunnelConnectionStarted(LocalTunnelServer localForwardingServer, LocalTunnelConnection activeTunnel) { 348 PortMonitor portMonitor = agent.getGUI().getPortMonitor(); 350 synchronized (portMonitor) { 351 int idx = portMonitor.getIndexForId(localForwardingServer.getId()); 352 AbstractPortItem item = portMonitor.getItemAt(idx); 353 item.increaseActive(); 354 portMonitor.updateItemAt(idx); 355 } 356 agent.updateInformation(); 357 TunnelManager.log.info("Tunnel has been opened on " + activeTunnel.getClientHost() + " to " + localForwardingServer.getTunnel().getDestinationHost() + ":" + localForwardingServer.getTunnel().getDestinationPort()); } 363 364 370 public void localTunnelConnectionStopped(LocalTunnelServer localForwardingServer, LocalTunnelConnection activeTunnel) { 371 372 PortMonitor portMonitor = agent.getGUI().getPortMonitor(); 374 synchronized (portMonitor) { 375 int idx = portMonitor.getIndexForId(localForwardingServer.getId()); 376 if (idx != -1) { 377 AbstractPortItem item = portMonitor.getItemAt(idx); 378 item.decreaseActive(); 379 portMonitor.updateItemAt(idx); 380 } 381 } 382 383 agent.updateInformation(); 384 385 TunnelManager.log.info("Tunnel has been closed on " + activeTunnel.getClientHost() + " to " + localForwardingServer.getTunnel().getDestinationHost() + ":" + localForwardingServer.getTunnel().getDestinationPort() + " ( single connect = " + localForwardingServer.getTunnel().isTemporarySingleConnect() + ", permanent = " + localForwardingServer.getTunnel().isPermanent() + " )"); 391 if (!localForwardingServer.isStopping() && localForwardingServer.getTunnel().isTemporarySingleConnect()) { 392 TunnelManager.log.info("Closing listening temporary listening socket"); localForwardingServer.stop(); 396 } 397 } 398 399 405 public void localTunnelDataTransferred(LocalTunnelServer localForwardingServer, byte[] buffer, int count, boolean sent) { 406 } 407 408 413 public void localTunnelServerStarted(LocalTunnelServer localForwardingServer) { 414 415 activeLocalTunnels.put(new Integer (localForwardingServer.getId()), localForwardingServer); 417 418 422 AbstractPortItem pi = new LocalPortItem(this, localForwardingServer.getTunnel(), localForwardingServer); 423 agent.getGUI().getPortMonitor().addPortItem(pi); 424 if (agent.getConfiguration().isDisplayInformationPopups()) { 425 agent.getGUI() 426 .popup(null, 427 MessageFormat.format(Messages.getString("TunnelManager.openedLocalTunnel"), new Object [] { localForwardingServer.getTunnel().getName(), String.valueOf(localForwardingServer.getTunnel().getSourcePort()), localForwardingServer.getTunnel().getDestinationHost() + ":" + localForwardingServer.getTunnel().getDestinationPort() }), Messages.getString("Agent.title"), "popup-tunnel", -1); } 432 agent.updateInformation(); 433 } 434 435 440 public void localTunnelStopped(LocalTunnelServer localForwardingServer) { 441 activeLocalTunnels.remove(new Integer (localForwardingServer.getId())); 442 synchronized (agent.getGUI().getPortMonitor()) { 443 int idx = agent.getGUI().getPortMonitor().getIndexForId(localForwardingServer.getId()); 444 if (idx != -1) { 445 agent.getGUI().getPortMonitor().removeItemAt(idx); 446 } 447 } 448 TunnelConfiguration listeningSocketConfiguration = localForwardingServer.getTunnel(); 449 if (agent.getConfiguration().isDisplayInformationPopups()) { 450 agent.getGUI() 451 .popup(null, 452 MessageFormat.format(Messages.getString("TunnelManager.closingLocalTunnel"), new Object [] { listeningSocketConfiguration.getName(), String.valueOf(listeningSocketConfiguration.getSourcePort()), 454 listeningSocketConfiguration.getDestinationHost() + ":" + listeningSocketConfiguration.getDestinationPort() }), Messages.getString("Agent.title"), "popup-tunnel", -1); } 458 agent.updateInformation(); 459 } 460 461 463 synchronized int getTemporaryTunnelId() { 464 return temporaryTunnelId--; 465 } 466 467 void processLaunchRequest(Request request) throws IOException { 468 472 if (request.getRequestData() == null) { 473 log.info("No request data returned, assuming launch was a remote tunnel"); 475 return; 477 } 478 startLocalTunnel(request.getRequestData()); 479 } 480 481 void stopLocalTunnel(Request request) { 482 483 if (request.getRequestData() == null) 484 return; 485 try { 486 ByteArrayReader msg = new ByteArrayReader(request.getRequestData()); 487 stopLocalTunnel(new Integer ((int) msg.readInt()), false); 488 request.setRequestData(null); 489 490 } catch (IOException ex) { 491 log.error("Failed to read tunnel id from request", ex); 493 } 495 } 496 497 void stopLocalTunnel(Integer id, boolean informServer) { 498 499 log.info("Stopping local tunnel with id" + id); 503 LocalTunnelServer listener = (LocalTunnelServer) activeLocalTunnels.get(id); 504 505 if (listener != null) { 506 listener.stop(); 507 } else { 508 log.error("Request to close unknown local tunnel " + id); 510 } 512 513 } 514 515 boolean startLocalTunnel(byte[] configurationData) { 516 517 try { 518 519 524 ByteArrayReader reply = new ByteArrayReader(configurationData); 525 String launchId = reply.readString(); 526 527 int id = (int) reply.readInt(); 528 String name = reply.readString(); 529 int type = (int) reply.readInt(); 530 String transport = reply.readString(); 531 String sourceInterface = reply.readString(); 532 int sourcePort = (int) reply.readInt(); 533 int destinationPort = (int) reply.readInt(); 534 String destinationHost = reply.readString(); 535 536 log.info("Received permanent tunnel named " + name + " for " + destinationHost + ":" + destinationPort); 538 540 DefaultTunnel t = new DefaultTunnel(id, 541 type, 542 transport, 543 sourceInterface, 544 sourcePort, 545 destinationPort, 546 destinationHost, 547 true, 548 false, 549 name, 550 launchId); 551 552 startLocalTunnel(t); 553 return true; 554 555 } catch (IOException e) { 556 log.error("Request permanent tunnels operation failed", e); 558 return false; 560 } 561 } 562 } 563 | Popular Tags |