/*
*
* Paros and its related class files.
*
* Paros is an HTTP/HTTPS proxy for assessing web application security.
* Copyright (C) 2003-2004 Chinotec Technologies Company
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the Clarified Artistic License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Clarified Artistic License for more details.
*
* You should have received a copy of the Clarified Artistic License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.parosproxy.paros.model;
import java.sql.SQLException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import org.parosproxy.paros.core.scanner.Alert;
import org.parosproxy.paros.db.RecordAlert;
import org.parosproxy.paros.db.RecordHistory;
import org.parosproxy.paros.db.RecordTag;
import org.parosproxy.paros.db.TableAlert;
import org.parosproxy.paros.db.TableHistory;
import org.parosproxy.paros.db.TableTag;
import org.parosproxy.paros.network.HttpMalformedHeaderException;
import org.parosproxy.paros.network.HttpMessage;
public class HistoryReference {
/**
* Temporary type = not retrieved from history. To be deleted.
*/
public static final int TYPE_TEMPORARY = 0;
public static final int TYPE_MANUAL = 1;
public static final int TYPE_SPIDER = 2;
public static final int TYPE_SCANNER = 3;
public static final int TYPE_SPIDER_SEED = 4;
public static final int TYPE_SPIDER_VISITED = 5;
public static final int TYPE_HIDDEN = 6;
public static final int TYPE_REQ_EDIT = 7;
// -ve means unsaved message;
public static final int TYPE_SPIDER_UNSAVE = -TYPE_SPIDER;
private static DecimalFormat decimalFormat = new java.text.DecimalFormat("##0.###");
private static TableHistory staticTableHistory = null;
// ZAP: Support for multiple tags
private static TableTag staticTableTag = null;
// ZAP: Support for loading alerts from db
private static TableAlert staticTableAlert = null;
// ZAP: Support for linking Alerts to Hrefs
private List<Alert> alerts = new ArrayList<Alert>();
private int historyId = 0;
private int historyType = TYPE_MANUAL;
private SiteNode siteNode = null;
private String display = null;
private long sessionId = 0;
/**
* @return Returns the sessionId.
*/
public long getSessionId() {
return sessionId;
}
public HistoryReference(int historyId) throws HttpMalformedHeaderException, SQLException {
RecordHistory history = null;
history = staticTableHistory.read(historyId);
HttpMessage msg = history.getHttpMessage();
// ZAP: Support for multiple tags
List<RecordTag> tags = staticTableTag.getTagsForHistoryID(historyId);
for (RecordTag tr : tags) {
msg.addTag(tr.getTag());
}
build(history.getSessionId(), history.getHistoryId(), history.getHistoryType(), msg);
// ZAP: Support for loading the alerts from the db
List<RecordAlert> alerts = staticTableAlert.getAlertsBySourceHistoryId(historyId);
for (RecordAlert alert: alerts) {
this.addAlert(new Alert(alert, this));
}
}
public HistoryReference(Session session, int historyType, HttpMessage msg)
throws HttpMalformedHeaderException, SQLException {
RecordHistory history = null;
history = staticTableHistory.write(session.getSessionId(), historyType, msg);
build(session.getSessionId(), history.getHistoryId(), history.getHistoryType(), msg);
// ZAP: Init HttpMessage HistoryReference field
msg.setHistoryRef(this);
// ZAP: Support for multiple tags
for (String tag : msg.getTags()) {
this.addTag(tag);
}
// ZAP: Support for loading the alerts from the db
List<RecordAlert> alerts = staticTableAlert.getAlertsBySourceHistoryId(historyId);
for (RecordAlert alert: alerts) {
this.addAlert(new Alert(alert, this));
}
}
private void build(long sessionId, int historyId, int historyType, HttpMessage msg) {
this.sessionId = sessionId;
this.historyId = historyId;
this.historyType = historyType;
if (historyType == TYPE_MANUAL) {
this.display = getDisplay(msg);
}
// ZAP: Init HttpMessage HistoryReference field
msg.setHistoryRef(this);
}
public static void setTableHistory(TableHistory tableHistory) {
staticTableHistory = tableHistory;
}
public static void setTableTag(TableTag tableTag) {
staticTableTag = tableTag;
}
public static void setTableAlert(TableAlert tableAlert) {
staticTableAlert = tableAlert;
}
/**
* @return Returns the historyId.
*/
public int getHistoryId() {
return historyId;
}
public HttpMessage getHttpMessage() throws HttpMalformedHeaderException, SQLException {
// fetch complete message
RecordHistory history = staticTableHistory.read(historyId);
if (history == null) {
return null;
}
if (history.getHttpMessage() != null) {
// ZAP: Support for multiple tags
List <RecordTag> tags = staticTableTag.getTagsForHistoryID(historyId);
for (RecordTag tag : tags) {
history.getHttpMessage().addTag(tag.getTag());
}
}
// ZAP: Init HttpMessage HistoryReference field
history.getHttpMessage().setHistoryRef(this);
return history.getHttpMessage();
}
public String toString() {
if (display != null) {
return display;
}
HttpMessage msg = null;
try {
msg = getHttpMessage();
display = getDisplay(msg);
} catch (HttpMalformedHeaderException e1) {
display = "";
} catch (SQLException e) {
display = "";
}
return display;
}
/**
* @return Returns the historyType.
*/
public int getHistoryType() {
return historyType;
}
/**
* Delete this HistoryReference from database
*
*/
public void delete() {
if (historyId > 0) {
try {
// ZAP: Support for multiple tags
staticTableTag.deleteTagsForHistoryID(historyId);
staticTableHistory.delete(historyId);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* @return Returns the siteNode.
*/
public SiteNode getSiteNode() {
return siteNode;
}
/**
* @param siteNode
* The siteNode to set.
*/
public void setSiteNode(SiteNode siteNode) {
this.siteNode = siteNode;
}
private String getDisplay(HttpMessage msg) {
StringBuffer sb = new StringBuffer(Integer.toString(historyId) + " ");
sb.append(msg.getRequestHeader().getPrimeHeader());
if (!msg.getResponseHeader().isEmpty()) {
sb.append(" \t=> " + msg.getResponseHeader().getPrimeHeader());
String diffTimeString = "\t [" + decimalFormat.format((double) (msg.getTimeElapsedMillis() / 1000.0)) + " s]";
sb.append(diffTimeString);
}
return sb.toString();
}
// ZAP: Support for multiple tags
public void addTag(String tag) {
try {
staticTableTag.insert(historyId, tag);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void deleteTag(String tag) {
try {
staticTableTag.delete(historyId, tag);
} catch (SQLException e) {
e.printStackTrace();
}
}
public List<String> getTags() {
List<String> tags = new ArrayList<String>();
try {
List<RecordTag> rTags = staticTableTag
.getTagsForHistoryID(historyId);
for (RecordTag rTag : rTags) {
tags.add(rTag.getTag());
}
} catch (SQLException e) {
e.printStackTrace();
}
return tags;
}
// ZAP: Added setNote method to HistoryReference
public void setNote(String note) {
try {
staticTableHistory.updateNote(historyId, note);
} catch (SQLException e) {
e.printStackTrace();
}
}
public synchronized void addAlert(Alert alert) {
for (Alert a : alerts) {
if (a.equals(alert)) {
// We've already recorded it
return;
}
}
this.alerts.add(alert);
if (this.siteNode != null) {
siteNode.addAlert(alert);
}
}
public synchronized void updateAlert(Alert alert) {
for (Alert a : alerts) {
if (a.getAlertId() == alert.getAlertId()) {
// Have to use the alertId instead of 'equals' as any of the
// other params might have changed
this.alerts.remove(a);
this.alerts.add(alert);
if (this.siteNode != null) {
siteNode.updateAlert(alert);
}
return;
}
}
}
public int getHighestAlert() {
int i = Alert.RISK_INFO;
for (Alert a : alerts) {
if (a.getRisk() > i) {
i = a.getRisk();
}
}
return i;
}
public List<Alert> getAlerts() {
return this.alerts;
}
public void setFlag(boolean flag) {
try {
staticTableHistory.updateFlag(historyId, flag);
} catch (SQLException e) {
e.printStackTrace();
}
}
}