/*
* Extensions.java
*
* meder: Plugin to check for common extensions of files (temporary files
* backup files and directory archives)
*
* Created on 04 December 2005, 08:52
*
* To change this template, choose Tools | Options and locate the template under
* the Source Creation and Management node. Right-click the template and choose
* Open. You can then make changes to the template in the Source Editor.
*/
package org.owasp.webscarab.plugin.extensions;
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
import org.owasp.webscarab.model.ConversationID;
import org.owasp.webscarab.model.HttpUrl;
import org.owasp.webscarab.model.Preferences;
import org.owasp.webscarab.model.Request;
import org.owasp.webscarab.model.Response;
import org.owasp.webscarab.model.StoreException;
import org.owasp.webscarab.plugin.Framework;
import org.owasp.webscarab.plugin.Hook;
import org.owasp.webscarab.plugin.Plugin;
import org.owasp.webscarab.plugin.extensions.ExtensionsModel;
import org.owasp.webscarab.httpclient.FetcherQueue;
import org.owasp.webscarab.httpclient.ConversationHandler;
import org.owasp.webscarab.model.UrlModel;
/**
*
* @author rdawes
*/
public class Extensions implements Plugin, ConversationHandler {
public static final int MAXLINKS = 100;
private Framework _framework;
private ExtensionsModel _model;
private FetcherQueue _fetcherQueue = null;
private int _threads = 4;
private int _delay = 100;
/** Creates a new instance of Extensions */
public Extensions(Framework framework) {
_framework = framework;
_model = new ExtensionsModel(framework.getModel());
try {
String property = "WebScarab.extensions.threads";
String threads = Preferences.getPreference(property, "4");
_threads = Integer.parseInt(threads);
property = "WebScarab.extensions.delay";
String delay = Preferences.getPreference(property, "100");
_delay = Integer.parseInt(delay);
} catch (NumberFormatException nfe) {
_threads = 4;
_delay = 100;
}
}
public void analyse(ConversationID id, Request request, Response response, String origin) {
}
public void flush() throws StoreException {
}
public String getPluginName() {
return "Extensions";
}
public Object getScriptableObject() {
return null;
}
public Hook[] getScriptingHooks() {
return new Hook[0];
}
public String getStatus() {
return _model.getStatus();
}
public boolean isBusy() {
return _model.isBusy();
}
public boolean isModified() {
return _model.isModified();
}
public boolean isRunning() {
return _model.isRunning();
}
public void run() {
_model.setRunning(true);
Request newReq;
HttpUrl origUrl;
_model.setStatus("Started");
_model.setStopping(false);
// start the fetchers
_fetcherQueue = new FetcherQueue(getPluginName(), this, _threads, _delay);
//try {
_model.setRunning(true);
while (!_model.isStopping()) {
origUrl = _model.dequeueURL();
if (origUrl == null) {
continue;
}
String[] exts;
if (origUrl.getPath().endsWith("/")) {
exts = _model.getDirectoryExtensions();
if (origUrl.getPath().length() < 2) {
continue;
}
} else {
exts = _model.getFileExtensions();
}
for (int ix = 0; ix < exts.length; ix++) {
_model.incrementExtensionsTested(origUrl);
newReq = newRequest(origUrl, exts[ix]);
_fetcherQueue.submit(newReq);
}
}
//}
_fetcherQueue.clearRequestQueue();
_fetcherQueue.stop();
_model.setRunning(false);
_model.setStatus("Stopped");
}
public void responseReceived(Response response) {
if (response.getStatus().equalsIgnoreCase("200")) {
_framework.addConversation(response.getRequest(), response, getPluginName());
}
}
public void requestError(Request request, IOException ioe) {
}
public void setSession(String type, Object store, String session) throws StoreException {
}
public boolean stop() {
_model.setRunning(false);
return _model.isRunning();
}
public synchronized String[] loadStrings(File file) throws IOException {
List<String> strings = new ArrayList<String>();
String line;
BufferedReader input = new BufferedReader(new FileReader(file));
while ((line = input.readLine()) != null) {
strings.add(line);
}
return (String[])strings.toArray(new String[0]);
}
public ExtensionsModel getModel() {
return _model;
}
public void checkExtensionsUnder(HttpUrl url) {
List<HttpUrl> links = new LinkedList<HttpUrl>();
queueLinksUnder(url, links, MAXLINKS);
while (links.size() > 0) _model.enqueueURL((HttpUrl)links.remove(0));
}
private void queueLinksUnder(HttpUrl url, List<HttpUrl> links, int max) {
if (!_model.isTested(url)) {
links.add(url);
}
if (links.size() == max) return;
UrlModel urlModel = _model.getUrlModel();
int count = urlModel.getChildCount(url);
for (int i=0; i<count; i++) {
HttpUrl child = urlModel.getChildAt(url, i);
queueLinksUnder(child, links, max);
if (links.size() == max) return;
}
}
public void checkExtensionsFor(HttpUrl urls[]) {
// I select a bunch of URL's, click check THESE
for (int ix=0; ix < urls.length; ix++) {
_model.enqueueURL(urls[ix]);
}
}
public void stopChecks() {
// Stop checks, let the other thread return ASAP
System.out.println("stopChecks()");
}
public Request newRequest(HttpUrl url, String ext) {
Request req = new Request();
String path = url.getPath();
try {
req.setMethod("GET");
req.setVersion("HTTP/1.0");
if (url.getPath().endsWith("/")) {
path = url.getPath();
path = path.substring(0, path.length() - 1);
}
req.setURL(new HttpUrl(url.getScheme() + "://" + url.getHost() + ":" + url.getPort() + path + ext));
req.setHeader("Host", url.getHost() + ":" + url.getPort());
req.setHeader("Connection", "Close");
}
catch (java.net.MalformedURLException e) {
return null;
}
/*
NamedValue[] headers = _model.getExtraHeaders();
if (headers != null && headers.length > 0) {
for (int i=0; i< headers.length; i++) {
if (headers[i] != null)
req.addHeader(headers[i]);
}
}
*/
return req;
}
}