Package com.subgraph.vega.impl.scanner

Source Code of com.subgraph.vega.impl.scanner.Scan

/*******************************************************************************
* Copyright (c) 2011 Subgraph.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Subgraph - initial API and implementation
******************************************************************************/
package com.subgraph.vega.impl.scanner;

import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.client.CookieStore;
import org.apache.http.cookie.Cookie;
import org.apache.http.params.HttpProtocolParams;

import com.subgraph.vega.api.events.IEvent;
import com.subgraph.vega.api.events.IEventHandler;
import com.subgraph.vega.api.http.requests.IHttpRequestEngine;
import com.subgraph.vega.api.http.requests.IHttpRequestEngineConfig;
import com.subgraph.vega.api.http.requests.IHttpRequestEngineFactory;
import com.subgraph.vega.api.model.IWorkspace;
import com.subgraph.vega.api.model.WorkspaceCloseEvent;
import com.subgraph.vega.api.model.WorkspaceResetEvent;
import com.subgraph.vega.api.model.alerts.IScanInstance;
import com.subgraph.vega.api.model.identity.IIdentity;
import com.subgraph.vega.api.model.requests.IRequestOriginScanner;
import com.subgraph.vega.api.scanner.IScan;
import com.subgraph.vega.api.scanner.IScanProbeResult;
import com.subgraph.vega.api.scanner.IScannerConfig;
import com.subgraph.vega.api.scanner.modules.IBasicModuleScript;
import com.subgraph.vega.api.scanner.modules.IResponseProcessingModule;
import com.subgraph.vega.api.scanner.modules.IScannerModule;
import com.subgraph.vega.api.scanner.modules.IScannerModuleRegistry;

public class Scan implements IScan {
  private final Scanner scanner;
  private final IEventHandler workspaceListener;
  private final IScannerConfig config;
  private IScanInstance scanInstance; // guarded by this
  private IWorkspace workspace; // guarded by this
  private ScanProbe scanProbe; // guarded by this
  private IHttpRequestEngine requestEngine; // guarded by this
  private ScannerTask scannerTask; // guarded by this
  private Thread scannerThread; // guarded by this
  private URI redirectURI = null;
  private List<IResponseProcessingModule> responseProcessingModules;
  private List<IBasicModuleScript> basicModules;

  /**
   * Instantiate a scan.
   * @param scanner Scanner the scan will be run with.
   * @param workspace Workspace to be used for the scan.
   * @return Scan.
   */
  public static Scan createScan(Scanner scanner, IWorkspace workspace) {
    if (workspace == null) {
      return null;
    }
    final Scan scan = new Scan(scanner);
    scan.setWorkspace(workspace);
    scan.reloadModules();
    return scan;
  }

  private Scan(Scanner scanner) {
    this.scanner = scanner;
    workspaceListener = new IEventHandler() {
      @Override
      public void handleEvent(IEvent event) {
        if (event instanceof WorkspaceCloseEvent || event instanceof WorkspaceResetEvent) {
          handleWorkspaceCloseOrReset();
        }
      }
    };
    config = new ScannerConfig();
  }

  private void setWorkspace(IWorkspace workspace) {
    synchronized(this) {
      workspace.lock();
      this.workspace = workspace;
      workspace.getModel().addWorkspaceListener(workspaceListener);
      scanInstance = workspace.getScanAlertRepository().createNewScanInstance();
      scanInstance.setScan(this);
    }
  }

  private void handleWorkspaceCloseOrReset() {
    synchronized(this) {
      scanInstance = null;
      workspace.getModel().removeWorkspaceListener(workspaceListener);
      workspace = null;
    }
  }
 
  @Override
  public IScannerConfig getConfig() {
    return config;
  }

  @Override
  public List<IScannerModule> getModuleList() {
    synchronized(this) {
      reloadModules();
      final List<IScannerModule> moduleList = new ArrayList<IScannerModule>();
      moduleList.addAll(responseProcessingModules);
      moduleList.addAll(basicModules);
      return moduleList;
    }
  }

  @Override
  public IScanProbeResult probeTargetUri(URI uri) {
    synchronized(this) {
      if (scanInstance == null) {
        throw new IllegalStateException("Scan is detached from workspace; scan instance was lost. A new scan must be created");
      }

      synchronized(scanInstance) {
        final int scanStatus = scanInstance.getScanStatus();
        if (scanStatus != IScanInstance.SCAN_CONFIG) {
          if (scanStatus != IScanInstance.SCAN_PROBING) {
            throw new IllegalStateException("Unable to run a probe for a scan that is already running or complete");
          } else {
            if (scanProbe != null) {
              throw new IllegalStateException("Another probe is already in progress");
            }
          }
        } else {
          requestEngine = createRequestEngine(config);
          workspace.getScanAlertRepository().addActiveScanInstance(scanInstance);
        }
       
        scanInstance.updateScanStatus(IScanInstance.SCAN_PROBING);
      }
     
      scanProbe = new ScanProbe(uri, requestEngine);
    }
    final IScanProbeResult probeResult = scanProbe.runProbe();
    synchronized(this) {
      scanProbe = null;
    }
    redirectURI = probeResult.getRedirectTarget();
    return probeResult;
  }

  @Override
  public void startScan() {
    synchronized(this) {
      if (scanInstance == null) {
        throw new IllegalStateException("Scan is detached from workspace; scan instance was lost. A new scan must be created");
      }

      if (config.getScanTargetScope() == null) {
        throw new IllegalArgumentException("Cannot start scan because no target was specified");
      }

      synchronized(scanInstance) {
        final int scanStatus = scanInstance.getScanStatus();
        if (scanStatus != IScanInstance.SCAN_CONFIG) {
          if (scanStatus != IScanInstance.SCAN_PROBING) {
            throw new IllegalStateException("Scan is already running or complete");
          } else {
            if (scanProbe != null) {
              throw new IllegalStateException("A scan probe is in progress");
            }
          }
        } else {
          requestEngine = createRequestEngine(config);
          workspace.getScanAlertRepository().addActiveScanInstance(scanInstance);
        }

        scanInstance.updateScanStatus(IScanInstance.SCAN_STARTING);
      }

      reloadModules();
      scannerTask = new ScannerTask(this);
      scannerThread = new Thread(scannerTask);
      scannerThread.start();
    }
  }

  @Override
  public void stopScan() {
    synchronized(this) {
      if(scannerTask != null) {
        scannerTask.stop();
      } else {
        if(scanProbe != null) {
          scanProbe.abort();
        }

        if (scanInstance != null) {
          synchronized(scanInstance) {
            if (scanInstance.getScanStatus() != IScanInstance.SCAN_CONFIG) {
              scanInstance.updateScanStatus(IScanInstance.SCAN_CANCELLED);
            }
          }
        }

        doFinish();
      }
    }
  }

  private IHttpRequestEngine createRequestEngine(IScannerConfig config) {
    final IHttpRequestEngineFactory requestEngineFactory = scanner.getHttpRequestEngineFactory();
    final IHttpRequestEngineConfig requestEngineConfig = requestEngineFactory.createConfig();

    if (config.getMaxRequestsPerSecond() > 0) {
      requestEngineConfig.setRequestsPerMinute(config.getMaxRequestsPerSecond() * 60);
    }
    requestEngineConfig.setMaxConnections(config.getMaxConnections());
    requestEngineConfig.setMaxConnectionsPerRoute(config.getMaxConnections());
    requestEngineConfig.setMaximumResponseKilobytes(config.getMaxResponseKilobytes());
   
    final IRequestOriginScanner requestOrigin = workspace.getRequestLog().getRequestOriginScanner(scanInstance);
    IHttpRequestEngine requestEngine = requestEngineFactory.createRequestEngine(IHttpRequestEngine.EngineConfigType.CONFIG_SCANNER, requestEngineConfig, requestOrigin);
    HttpProtocolParams.setUserAgent(requestEngine.getHttpClient().getParams(), config.getUserAgent());
    // REVISIT: consider moving authentication method to request engine config
    IIdentity identity = config.getScanIdentity();
    if (identity != null && identity.getAuthMethod() != null) {
      identity.getAuthMethod().setAuth(requestEngine);
    }
   
    if (config.getCookieList() != null && !config.getCookieList().isEmpty()) {
      CookieStore cookieStore = requestEngine.getCookieStore();
      for (Cookie c: config.getCookieList()) {
        cookieStore.addCookie(c);
      }
    }   

    return requestEngine;
  }

  private void reloadModules() {
    IScannerModuleRegistry moduleRegistry = scanner.getScannerModuleRegistry();
    if(responseProcessingModules == null || basicModules == null) {
      responseProcessingModules = moduleRegistry.getResponseProcessingModules();
      basicModules = moduleRegistry.getBasicModules();
    } else {
      responseProcessingModules = moduleRegistry.updateResponseProcessingModules(responseProcessingModules);
      basicModules = moduleRegistry.updateBasicModules(basicModules);
    }
  }

  public Scanner getScanner() {
    return scanner;
  }

  public synchronized IScanInstance getScanInstance() {
    return scanInstance;
  }

  public synchronized IWorkspace getWorkspace() {
    return workspace;
  }

  public synchronized List<IResponseProcessingModule> getResponseModules() {
    return responseProcessingModules;
  }
 
  public synchronized List<IBasicModuleScript> getBasicModules() {
    return basicModules;
  }

  public synchronized IHttpRequestEngine getRequestEngine() {
    return requestEngine;
  }

  public void doFinish() {
    synchronized(this) {
      scanInstance.setScan(null);
      workspace.getScanAlertRepository().removeActiveScanInstance(scanInstance);
      workspace.unlock();
    }
  }

  public URI getRedirectURI() {
    return redirectURI;
  }

  @Override
  public void pauseScan() {
    if(scannerTask != null) {
      scannerTask.pauseScan();
    }
  }

  @Override
  public void unpauseScan() {
    if(scannerTask != null) {
      scannerTask.unpauseScan();
    }
  }

  @Override
  public boolean isPausedScan() {
    if(scannerTask != null) {
      return scannerTask.isPaused();
    } else {
      return false;
    }
  }
}
TOP

Related Classes of com.subgraph.vega.impl.scanner.Scan

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.