/*
* SpiderModel.java
*
* Created on 04 March 2005, 03:11
*/
package org.owasp.webscarab.plugin.spider;
import org.owasp.webscarab.model.UrlModel;
import org.owasp.webscarab.model.Cookie;
import org.owasp.webscarab.model.NamedValue;
import org.owasp.webscarab.model.HttpUrl;
import org.owasp.webscarab.model.Preferences;
import org.owasp.webscarab.model.FrameworkModel;
import org.owasp.webscarab.model.FilteredUrlModel;
import org.owasp.webscarab.plugin.AbstractPluginModel;
import java.util.List;
import java.util.LinkedList;
import java.util.logging.Logger;
/**
*
* @author rogan
*/
public class SpiderModel extends AbstractPluginModel {
private FrameworkModel _model;
private SpiderUrlModel _urlModel;
private List<Link> _linkQueue = new LinkedList<Link>();
private String _allowedDomains = null;
private String _forbiddenPaths = null;
private boolean _recursive = false;
private boolean _cookieSync = false;
private NamedValue[] _extraHeaders = null;
private Logger _logger = Logger.getLogger(getClass().getName());
/** Creates a new instance of SpiderModel */
public SpiderModel(FrameworkModel model) {
_model = model;
_urlModel = new SpiderUrlModel(_model.getUrlModel());
parseProperties();
}
public UrlModel getUrlModel() {
return _urlModel;
}
public boolean isUnseen(HttpUrl url) {
return _model.getUrlProperty(url, "METHODS") == null;
}
public boolean isForbidden(HttpUrl url) {
if (_forbiddenPaths != null && !_forbiddenPaths.equals("")) {
try {
return url.toString().matches(getForbiddenPaths());
} catch (Exception e) {
}
}
return false;
}
public void addUnseenLink(HttpUrl url, HttpUrl referer) {
if (url == null) {
return;
}
if (isUnseen(url)) {
String first = _model.getUrlProperty(url, "REFERER");
if (first == null || first.equals("")) {
_model.setUrlProperty(url, "REFERER", referer.toString());
}
}
}
public void queueLink(Link link) {
// _logger.info("Queueing " + link);
try {
_model.readLock().acquire();
_linkQueue.add(link);
} catch (InterruptedException ie) {
_logger.warning("Interrupted waiting for the read lock! " + ie.getMessage());
} finally {
_model.readLock().release();
}
// _logger.info("Done queuing " + link);
}
public Link dequeueLink() {
// _logger.info("Dequeueing a link");
Link link = null;
try {
_model.readLock().acquire();
if (_linkQueue.size() > 0)
link = _linkQueue.remove(0);
if (_linkQueue.size() == 0) {
setStatus("Idle");
} else {
setStatus(_linkQueue.size() + " links remaining");
}
} catch (InterruptedException ie) {
_logger.warning("Interrupted waiting for the read lock! " + ie.getMessage());
} finally {
_model.readLock().release();
// _logger.info("Done dequeuing a link " + link);
}
return link;
}
public void clearLinkQueue() {
try {
_model.readLock().acquire();
_linkQueue.clear();
} catch (InterruptedException ie) {
_logger.warning("Interrupted waiting for the read lock! " + ie.getMessage());
} finally {
_model.readLock().release();
}
}
public int getQueuedLinkCount() {
try {
_model.readLock().acquire();
return _linkQueue.size();
} catch (InterruptedException ie) {
_logger.warning("Interrupted waiting for the read lock! " + ie.getMessage());
} finally {
_model.readLock().release();
}
return 0;
}
public Cookie[] getCookiesForUrl(HttpUrl url) {
return _model.getCookiesForUrl(url);
}
public void addCookie(Cookie cookie) {
_model.addCookie(cookie);
}
public void parseProperties() {
String prop = "Spider.domains";
String value = Preferences.getPreference(prop, ".*localhost.*");
setAllowedDomains(value);
prop = "Spider.excludePaths";
value = Preferences.getPreference(prop, "");
setForbiddenPaths(value);
prop = "Spider.synchroniseCookies";
value = Preferences.getPreference(prop, "true");
setCookieSync(value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes"));
prop = "Spider.recursive";
value = Preferences.getPreference(prop, "false");
setRecursive(value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes"));
}
public String getReferer(HttpUrl url) {
return _model.getUrlProperty(url, "REFERER");
}
public void setExtraHeaders(NamedValue[] headers) {
_extraHeaders = headers;
}
public NamedValue[] getExtraHeaders() {
return _extraHeaders;
}
public void setRecursive(boolean bool) {
_recursive = bool;
String prop = "Spider.recursive";
Preferences.setPreference(prop,Boolean.toString(bool));
}
public boolean getRecursive() {
return _recursive;
}
public void setCookieSync(boolean enabled) {
_cookieSync = enabled;
String prop = "Spider.synchroniseCookies";
Preferences.setPreference(prop,Boolean.toString(enabled));
}
public boolean getCookieSync() {
return _cookieSync;
}
public void setAllowedDomains(String regex) {
_allowedDomains = regex;
String prop = "Spider.domains";
Preferences.setPreference(prop,regex);
}
public String getAllowedDomains() {
return _allowedDomains;
}
public void setForbiddenPaths(String regex) {
_forbiddenPaths = regex;
String prop = "Spider.excludePaths";
Preferences.setPreference(prop,regex);
_urlModel.reset();
}
public String getForbiddenPaths() {
return _forbiddenPaths;
}
public void setAuthRequired(HttpUrl url) {
_model.setUrlProperty(url, "AUTHREQUIRED", Boolean.toString(true));
}
private class SpiderUrlModel extends FilteredUrlModel {
public SpiderUrlModel(UrlModel model) {
super(model);
}
public boolean shouldFilter(HttpUrl url) {
return ! isUnseen(url) || isForbidden(url);
}
}
}