/* * Zed Attack Proxy (ZAP) and its related class files. * * ZAP is an HTTP/HTTPS proxy for assessing web application security. * * Copyright 2010 psiinon@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.zaproxy.zap.extension.httpsessions; import java.awt.CardLayout; import java.awt.Event; import java.awt.EventQueue; import java.awt.GridBagConstraints; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyEvent; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToolBar; import javax.swing.KeyStroke; import org.jdesktop.swingx.JXTable; import org.parosproxy.paros.Constant; import org.parosproxy.paros.control.Control; import org.parosproxy.paros.extension.AbstractPanel; import org.parosproxy.paros.model.SiteNode; import org.parosproxy.paros.view.View; import org.zaproxy.zap.utils.DisplayUtils; import org.zaproxy.zap.utils.SortedComboBoxModel; import org.zaproxy.zap.view.ScanPanel; /** * The HttpSessionsPanel used as a display panel for the {@link ExtensionHttpSessions}, allowing the * user to view and control the http sessions. */ public class HttpSessionsPanel extends AbstractPanel { /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** The Constant PANEL_NAME. */ public static final String PANEL_NAME = "httpsessions"; /** The extension. */ private ExtensionHttpSessions extension = null; private JPanel panelCommand = null; private JToolBar panelToolbar = null; private JScrollPane jScrollPane = null; private JComboBox<String> siteSelect = null; private JButton newSessionButton = null; private JXTable sessionsTable = null; private JButton optionsButton = null; /** The current site. */ private String currentSite = null; /** The site model. */ private SortedComboBoxModel<String> siteModel = new SortedComboBoxModel<>(); /** The sessions model. */ private HttpSessionsTableModel sessionsModel = new HttpSessionsTableModel(null); /** * Instantiates a new http session panel. * * @param extensionHttpSession the extension http session */ public HttpSessionsPanel(ExtensionHttpSessions extensionHttpSession) { super(); this.extension = extensionHttpSession; initialize(); } /** * This method initializes this panel. */ private void initialize() { this.setLayout(new CardLayout()); this.setSize(474, 251); this.setName(Constant.messages.getString("httpsessions.panel.title")); this.setIcon(new ImageIcon(HttpSessionsPanel.class.getResource("/resource/icon/16/session.png"))); this.setDefaultAccelerator(KeyStroke.getKeyStroke( KeyEvent.VK_H, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | Event.ALT_MASK | Event.SHIFT_MASK, false)); this.setMnemonic(Constant.messages.getChar("httpsessions.panel.mnemonic")); this.add(getPanelCommand(), getPanelCommand().getName()); } /** * This method initializes the main panel. * * @return javax.swing.JPanel */ private javax.swing.JPanel getPanelCommand() { if (panelCommand == null) { panelCommand = new javax.swing.JPanel(); panelCommand.setLayout(new java.awt.GridBagLayout()); panelCommand.setName(Constant.messages.getString("httpsessions.panel.title")); // Add the two components: toolbar and work pane GridBagConstraints toolbarGridBag = new GridBagConstraints(); GridBagConstraints workPaneGridBag = new GridBagConstraints(); toolbarGridBag.gridx = 0; toolbarGridBag.gridy = 0; toolbarGridBag.weightx = 1.0d; toolbarGridBag.insets = new java.awt.Insets(2, 2, 2, 2); toolbarGridBag.anchor = java.awt.GridBagConstraints.NORTHWEST; toolbarGridBag.fill = java.awt.GridBagConstraints.HORIZONTAL; workPaneGridBag.gridx = 0; workPaneGridBag.gridy = 1; workPaneGridBag.weightx = 1.0; workPaneGridBag.weighty = 1.0; workPaneGridBag.insets = new java.awt.Insets(0, 0, 0, 0); workPaneGridBag.anchor = java.awt.GridBagConstraints.NORTHWEST; workPaneGridBag.fill = java.awt.GridBagConstraints.BOTH; panelCommand.add(this.getPanelToolbar(), toolbarGridBag); panelCommand.add(getWorkPane(), workPaneGridBag); } return panelCommand; } /** * Gets the options button. * * @return the options button */ private JButton getOptionsButton() { if (optionsButton == null) { optionsButton = new JButton(); optionsButton.setToolTipText(Constant.messages.getString("httpsessions.toolbar.options.button")); optionsButton.setIcon(DisplayUtils.getScaledIcon(new ImageIcon(ScanPanel.class.getResource("/resource/icon/16/041.png")))); optionsButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Control.getSingleton().getMenuToolsControl() .options(Constant.messages.getString("httpsessions.options.title")); } }); } return optionsButton; } /** * Gets the new session button. * * @return the new session button */ private JButton getNewSessionButton() { if (newSessionButton == null) { newSessionButton = new JButton(); newSessionButton.setText(Constant.messages.getString("httpsessions.toolbar.newsession.label")); newSessionButton.setIcon(DisplayUtils.getScaledIcon(new ImageIcon(HttpSessionsPanel.class.getResource("/resource/icon/16/103.png")))); newSessionButton.setToolTipText(Constant.messages.getString("httpsessions.toolbar.newsession.tooltip")); newSessionButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { HttpSessionsSite site = getCurrentHttpSessionSite(); if (site != null) { site.createEmptySession(); } } }); } return newSessionButton; } /** * Gets the panel's toolbar. * * @return the panel toolbar */ private javax.swing.JToolBar getPanelToolbar() { if (panelToolbar == null) { // Initialize the toolbar panelToolbar = new javax.swing.JToolBar(); panelToolbar.setLayout(new java.awt.GridBagLayout()); panelToolbar.setEnabled(true); panelToolbar.setFloatable(false); panelToolbar.setRollover(true); panelToolbar.setPreferredSize(new java.awt.Dimension(800, 30)); panelToolbar.setName("HttpSessionToolbar"); // Add elements GridBagConstraints labelGridBag = new GridBagConstraints(); GridBagConstraints siteSelectGridBag = new GridBagConstraints(); GridBagConstraints newSessionGridBag = new GridBagConstraints(); GridBagConstraints emptyGridBag = new GridBagConstraints(); GridBagConstraints optionsGridBag = new GridBagConstraints(); labelGridBag.gridx = 0; labelGridBag.gridy = 0; labelGridBag.insets = new java.awt.Insets(0, 0, 0, 0); labelGridBag.anchor = java.awt.GridBagConstraints.WEST; siteSelectGridBag.gridx = 1; siteSelectGridBag.gridy = 0; siteSelectGridBag.insets = new java.awt.Insets(0, 0, 0, 0); siteSelectGridBag.anchor = java.awt.GridBagConstraints.WEST; newSessionGridBag.gridx = 2; newSessionGridBag.gridy = 0; newSessionGridBag.insets = new java.awt.Insets(0, 0, 0, 0); newSessionGridBag.anchor = java.awt.GridBagConstraints.WEST; emptyGridBag.gridx = 3; emptyGridBag.gridy = 0; emptyGridBag.weightx = 1.0; emptyGridBag.weighty = 1.0; emptyGridBag.insets = new java.awt.Insets(0, 0, 0, 0); emptyGridBag.anchor = java.awt.GridBagConstraints.WEST; emptyGridBag.fill = java.awt.GridBagConstraints.HORIZONTAL; optionsGridBag.gridx = 4; optionsGridBag.gridy = 0; optionsGridBag.insets = new java.awt.Insets(0, 0, 0, 0); optionsGridBag.anchor = java.awt.GridBagConstraints.EAST; JLabel label = new JLabel(Constant.messages.getString("httpsessions.toolbar.site.label")); panelToolbar.add(label, labelGridBag); panelToolbar.add(getSiteSelect(), siteSelectGridBag); panelToolbar.add(getNewSessionButton(), newSessionGridBag); panelToolbar.add(getOptionsButton(), optionsGridBag); // Add an empty JLabel to fill the space panelToolbar.add(new JLabel(), emptyGridBag); } return panelToolbar; } /** * Gets the work pane where data is shown. * * @return the work pane */ private JScrollPane getWorkPane() { if (jScrollPane == null) { jScrollPane = new JScrollPane(); jScrollPane.setViewportView(getHttpSessionsTable()); } return jScrollPane; } /** * Sets the sessions table column sizes. */ private void setSessionsTableColumnSizes() { sessionsTable.getColumnModel().getColumn(0).setMinWidth(60); sessionsTable.getColumnModel().getColumn(0).setPreferredWidth(60); // active sessionsTable.getColumnModel().getColumn(1).setMinWidth(120); sessionsTable.getColumnModel().getColumn(1).setPreferredWidth(200); // name sessionsTable.getColumnModel().getColumn(3).setMinWidth(100); sessionsTable.getColumnModel().getColumn(3).setPreferredWidth(150); // matched } /** * Gets the http sessions table. * * @return the http sessions table */ private JXTable getHttpSessionsTable() { if (sessionsTable == null) { sessionsTable = new JXTable(sessionsModel); sessionsTable.setColumnSelectionAllowed(false); sessionsTable.setCellSelectionEnabled(false); sessionsTable.setRowSelectionAllowed(true); sessionsTable.setAutoCreateRowSorter(true); sessionsTable.setColumnControlVisible(true); this.setSessionsTableColumnSizes(); sessionsTable.setName(PANEL_NAME); sessionsTable.setDoubleBuffered(true); sessionsTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); sessionsTable.addMouseListener(new java.awt.event.MouseAdapter() { @Override public void mousePressed(java.awt.event.MouseEvent e) { showPopupMenuIfTriggered(e); } @Override public void mouseReleased(java.awt.event.MouseEvent e) { showPopupMenuIfTriggered(e); } private void showPopupMenuIfTriggered(java.awt.event.MouseEvent e) { if (e.isPopupTrigger()) { // Select table item int row = sessionsTable.rowAtPoint(e.getPoint()); if (row < 0 || !sessionsTable.getSelectionModel().isSelectedIndex(row)) { sessionsTable.getSelectionModel().clearSelection(); if (row >= 0) { sessionsTable.getSelectionModel().setSelectionInterval(row, row); } } View.getSingleton().getPopupMenu().show(e.getComponent(), e.getX(), e.getY()); } } }); } return sessionsTable; } /** * Gets the site select ComboBox. * * @return the site select */ private JComboBox<String> getSiteSelect() { if (siteSelect == null) { siteSelect = new JComboBox<>(siteModel); siteSelect.addItem(Constant.messages.getString("httpsessions.toolbar.site.select")); siteSelect.setSelectedIndex(0); // Add the item listener for when the site is selected siteSelect.addItemListener(new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { if (ItemEvent.SELECTED == e.getStateChange()) { if (siteSelect.getSelectedIndex() > 0) { siteSelected((String) e.getItem()); } // If the user selects the first option (empty one), force the selection to // the first valid site else if (siteModel.getSize() > 1) { siteModel.setSelectedItem(siteModel.getElementAt(1)); } } } }); } return siteSelect; } /** * Adds a new site to the "Http Sessions" tab. * <p> * The method must be called in the EDT, failing to do so might result in thread interference or memory consistency errors. * </p> * * @param site the site * @see #addSiteAsynchronously(String) * @see EventQueue */ public void addSite(String site) { if (siteModel.getIndexOf(site) < 0) { siteModel.addElement(site); if (currentSite == null) { // First site added, automatically select it siteModel.setSelectedItem(site); } } } /** * Adds a new site, asynchronously, to the "Http Sessions" tab. * <p> * The call to this method will return immediately and the site will be added in the EDT (by calling the method * {@code EventQueue#invokeLater(Runnable)}) after all pending events have been processed. * </p> * * @param site the site * @see #addSite(String) * @see EventQueue#invokeLater(Runnable) */ public void addSiteAsynchronously(final String site) { EventQueue.invokeLater(new Runnable() { @Override public void run() { addSite(site); } }); } /** * A new Site was selected. * * @param site the site */ private void siteSelected(String site) { if (!site.equals(currentSite)) { this.sessionsModel = extension.getHttpSessionsSite(site).getModel(); this.getHttpSessionsTable().setModel(this.sessionsModel); this.setSessionsTableColumnSizes(); currentSite = site; } } /** * Node selected. * * @param node the node */ public void nodeSelected(SiteNode node) { if (node != null) { siteModel.setSelectedItem(ScanPanel.cleanSiteName(node, true)); } } /** * Reset the panel. */ public void reset() { currentSite = null; siteModel.removeAllElements(); siteModel.addElement(Constant.messages.getString("httpsessions.toolbar.site.select")); sessionsModel = new HttpSessionsTableModel(null); getHttpSessionsTable().setModel(sessionsModel); } /** * Gets the current http session site. * * @return the current http session site, or null if no HttpSessionSite is selected */ public HttpSessionsSite getCurrentHttpSessionSite() { if (currentSite == null) { return null; } return extension.getHttpSessionsSite(currentSite); } /** * Gets the currently selected site. * * @return the current site */ public String getCurrentSite(){ return currentSite; } /** * Gets the selected http session. * * @return the selected session, or null if nothing is selected */ public HttpSession getSelectedSession() { final int selectedRow = this.sessionsTable.getSelectedRow(); if (selectedRow == -1) { // No row selected return null; } final int rowIndex = sessionsTable.convertRowIndexToModel(selectedRow); return this.sessionsModel.getHttpSessionAt(rowIndex); } }