All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.parosproxy.paros.control.MenuFileControl Maven / Gradle / Ivy

Go to download

The Zed Attack Proxy (ZAP) is an easy to use integrated penetration testing tool for finding vulnerabilities in web applications. It is designed to be used by people with a wide range of security experience and as such is ideal for developers and functional testers who are new to penetration testing. ZAP provides automated scanners as well as a set of tools that allow you to find security vulnerabilities manually.

There is a newer version: 2.16.0
Show newest version
/*
 *
 * 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.
 */
// ZAP: 2011/05/15 Improved error logging
// ZAP: 2012/02/18 Rationalised session handling
// ZAP: 2012/04/23 Added @Override annotation to all appropriate methods.
// ZAP: 2012/06/11 Changed to call the method Control.shutdown(boolean) with the
// parameter set as true.
// ZAP: 2012/06/19 Changed the method sessionOpened(File,Exception) to not call
// the method ExtensionLoader.sessionChangedAllPlugin, now it's done in the
// class Control.
// ZAP: 2012/07/02 Changed to use the new database compact option in the method
// exit().
// ZAP: 2012/07/23 Removed parameter from View.getSessionDialog call.
// ZAP: 2012/12/06 Issue 428: Moved exit code to control to support the marketplace
// ZAP: 2013/01/25 Removed the "(non-Javadoc)" comments.
// ZAP: 2013/03/03 Issue 546: Remove all template Javadoc comments
// ZAP: 2013/03/03 Issue 547: Deprecate unused classes and methods
// ZAP: 2013/04/16 Issue 638: Persist and snapshot sessions instead of saving them
// ZAP: 2013/08/05 Proper call for starting Session Properties dialog
// ZAP: 2013/08/28 Issue 695: Sites tree doesnt clear on new session created by API
// ZAP: 2014/05/20 Issue 1191: Cmdline session params have no effect
// ZAP: 2014/12/22 Issue 1476: Display contexts in the Sites tree
// ZAP: 2015/01/29 Issue 1489: Version number in window title
// ZAP: 2015/02/05 Issue 1524: New Persist Session dialog
// ZAP: 2015/04/02 Issue 321: Support multiple databases
// ZAP: 2015/12/14 Log exception and internationalise error message
// ZAP: 2016/10/26 Issue 1952: Do not allow Contexts with same name
// ZAP: 2017/02/25 Issue 2618: Let the user select the name for snapshots

package org.parosproxy.paros.control;
 
import java.awt.EventQueue;
import java.io.File;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.parosproxy.paros.Constant;
import org.parosproxy.paros.db.Database;
import org.parosproxy.paros.db.DatabaseException;
import org.parosproxy.paros.db.RecordSession;
import org.parosproxy.paros.extension.option.DatabaseParam;
import org.parosproxy.paros.model.Model;
import org.parosproxy.paros.model.Session;
import org.parosproxy.paros.model.SessionListener;
import org.parosproxy.paros.view.View;
import org.parosproxy.paros.view.WaitMessageDialog;
import org.zaproxy.zap.model.IllegalContextNameException;
import org.zaproxy.zap.view.ContextExportDialog;
import org.zaproxy.zap.view.PersistSessionDialog;
import org.zaproxy.zap.view.SessionTableSelectDialog;


public class MenuFileControl implements SessionListener {

    private static Logger log = Logger.getLogger(MenuFileControl.class);

    private View view = null;
    private Model model = null;
    private Control control = null;
    private WaitMessageDialog waitMessageDialog = null;
    
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd-HHmmss");
    
    public MenuFileControl(Model model, View view, Control control) {
        this.view = view;
        this.model = model;
        this.control = control;
    }
    
	public void exit() {
		control.exit(false, null);
	}
	
	public void newSession(boolean isPromptNewSession) throws ClassNotFoundException, Exception {
		
		if (isPromptNewSession) {
			// ZAP: i18n
		    if (model.getSession().isNewState()) {
				if (view.showConfirmDialog(Constant.messages.getString("menu.file.discardSession")) != JOptionPane.OK_OPTION) {
					return;
				}
				control.discardSession();
		    } else if (view.showConfirmDialog(Constant.messages.getString("menu.file.closeSession")) != JOptionPane.OK_OPTION) {
				return;
			}
		}
		
		int newSessionOption = model.getOptionsParam().getDatabaseParam().getNewSessionOption();

		if (model.getOptionsParam().getDatabaseParam().isNewSessionPrompt()) {
			PersistSessionDialog psd = new PersistSessionDialog(View.getSingleton().getMainFrame());
			// Set up the default option - ie the same one the user chose last time
			switch (newSessionOption) {
				case DatabaseParam.NEW_SESSION_TIMESTAMPED: 
					psd.setTimestampChosen();
					break;
				case DatabaseParam.NEW_SESSION_USER_SPECIFIED:
					psd.setPersistChosen();
					break;
				case DatabaseParam.NEW_SESSION_TEMPORARY:
					psd.setTemporaryChosen();
					break;
				default:
					break;
			}
	
			psd.setVisible(true);
			
			if (psd.isTimestampChosen()) {
				newSessionOption = DatabaseParam.NEW_SESSION_TIMESTAMPED;
			} else if (psd.isPersistChosen()) {
				newSessionOption = DatabaseParam.NEW_SESSION_USER_SPECIFIED;
			} else {
				newSessionOption = DatabaseParam.NEW_SESSION_TEMPORARY;
			}
			// Save for next time
			model.getOptionsParam().getDatabaseParam().setNewSessionOption(newSessionOption);
			model.getOptionsParam().getDatabaseParam().setNewSessionPrompt(!psd.isDontAskAgain());
		}
		
		switch (newSessionOption) {
			case DatabaseParam.NEW_SESSION_TIMESTAMPED: 
				String filename = getTimestampFilename();
				if (filename != null) {
					this.newSession(filename);
				} else {
					control.newSession();
				}
				break;
			case DatabaseParam.NEW_SESSION_USER_SPECIFIED:
				control.newSession();
				this.saveAsSession();
				break;
			default:
				control.newSession();
				break;
		}
	}
	
	private String getTimestampFilename() {
		File dir = new File(Constant.getZapHome(), "sessions");
		if (! dir.exists()) {
			if (! dir.mkdirs()) {
				return null;
			}
		}
		String timestamp = dateFormat.format(new Date());
		File tmpFile = new File(dir, timestamp + ".session");
		return tmpFile.getAbsolutePath();
	}
	
    public boolean newSession(String fileName) {
        final Object[] created = { Boolean.TRUE };
        waitMessageDialog = view.getWaitMessageDialog(Constant.messages.getString("menu.file.newSession.wait.dialogue"));
        control.newSession(fileName, new SessionListener() {

            @Override
            public void sessionSnapshot(Exception e) {
            }

            @Override
            public void sessionSaved(final Exception e) {
                if (EventQueue.isDispatchThread()) {
                    if (e == null) {
                        setTitle();
                        view.getSiteTreePanel().getTreeSite().setModel(model.getSession().getSiteTree());
                    } else {
                        view.showWarningDialog(Constant.messages.getString("menu.file.newSession.error"));
                        log.error("Error creating session file " + model.getSession().getFileName(), e);
                        created[0] = Boolean.FALSE;
                    }

                    if (waitMessageDialog != null) {
                        waitMessageDialog.setVisible(false);
                        waitMessageDialog = null;
                    }
                } else {
                    EventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            sessionSaved(e);
                        }
                    });
                }
            }

            @Override
            public void sessionOpened(File file, Exception e) {
            }
        });

        waitMessageDialog.setVisible(true);
        return created[0] == Boolean.TRUE;
    }
    
    public boolean openSession(String session) {
        final Object[] opened = { Boolean.TRUE };
        File sessionFile = new File(session);
        waitMessageDialog = view.getWaitMessageDialog(Constant.messages.getString("menu.file.loadSession"));
        log.info("opening session file " + sessionFile.getAbsolutePath());
        control.openSession(sessionFile, new SessionListener() {

            @Override
            public void sessionSnapshot(Exception e) {
            }

            @Override
            public void sessionSaved(Exception e) {
            }

            @Override
            public void sessionOpened(final File file, final Exception e) {
                if (EventQueue.isDispatchThread()) {
                    if (e != null) {
                        view.showWarningDialog(Constant.messages.getString("menu.file.openSession.error"));
                        log.error("error opening session file " + model.getSession().getFileName(), e);
                        opened[0] = Boolean.FALSE;
                    }

                    view.getSiteTreePanel().getTreeSite().setModel(model.getSession().getSiteTree());
                    setTitle();

                    if (waitMessageDialog != null) {
                        waitMessageDialog.setVisible(false);
                        waitMessageDialog = null;
                    }
                } else {
                    EventQueue.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            sessionOpened(file, e);
                        }
                    });
                }
            }
        });
        waitMessageDialog.setVisible(true);
        
        return opened[0] == Boolean.TRUE;
    }

	public void openSession() {
		// TODO extract into db specific classes??
		if (Database.DB_TYPE_HSQLDB.equals(model.getDb().getType())) {
			this.openFileBasedSession();
		} else {
			this.openDbBasedSession();
		}
	}
	
	private void openFileBasedSession () {
		JFileChooser chooser = new JFileChooser(model.getOptionsParam().getUserDirectory());
		chooser.setFileHidingEnabled(false);	// By default ZAP on linux puts timestamped sessions under a 'dot' directory 
		File file = null;
	    chooser.setFileFilter(new FileFilter() {
	           @Override
	           public boolean accept(File file) {
	                if (file.isDirectory()) {
	                    return true;
	                } else if (file.isFile() && file.getName().endsWith(".session")) {
	                    return true;
	                }
	                return false;
	            }
	           @Override
	           public String getDescription() {
	        	   // ZAP: Rebrand
	               return Constant.messages.getString("file.format.zap.session");
	           }
	    });
	    int rc = chooser.showOpenDialog(view.getMainFrame());
	    if(rc == JFileChooser.APPROVE_OPTION) {
			try {
	    		file = chooser.getSelectedFile();
	    		if (file == null) {
	    			return;
	    		}
                model.getOptionsParam().setUserDirectory(chooser.getCurrentDirectory());
	    	    log.info("opening session file " + file.getAbsolutePath());
	    	    waitMessageDialog = view.getWaitMessageDialog(Constant.messages.getString("menu.file.loadSession"));
	    	    control.openSession(file, this);
	    		waitMessageDialog.setVisible(true);
			} catch (Exception e) {
	            log.error(e.getMessage(), e);
			}
	    }
	}
	
	private void openDbBasedSession() {
		try {
			List sessionList = new ArrayList();
			for (RecordSession rs : model.getDb().getTableSession().listSessions()) {
				sessionList.add(""+rs.getSessionId());
			}
			SessionTableSelectDialog ssd = new SessionTableSelectDialog(View.getSingleton().getMainFrame(), sessionList);
			ssd.setVisible(true);
			
			if (ssd.getSelectedSession() != null) {
	    	    waitMessageDialog = view.getWaitMessageDialog(Constant.messages.getString("menu.file.loadSession"));
	    	    control.openSession(ssd.getSelectedSession(), this);
	    		waitMessageDialog.setVisible(true);
			}

		} catch (DatabaseException e) {
            log.error(e.getMessage(), e);
		}
	}
	
	public void saveSession() {
	    Session session = model.getSession();

	    if (session.isNewState()) {
		    view.showWarningDialog("Please use Save As...");
		    return;
	    }
	    
		try {
    	    waitMessageDialog = view.getWaitMessageDialog(Constant.messages.getString("menu.file.savingSession"));	// ZAP: i18n   
    		control.saveSession(session.getFileName(), this);
    	    log.info("saving session file " + session.getFileName());
    	    // ZAP: If the save is quick the dialog can already be null here
    	    if (waitMessageDialog != null) {
    	    	waitMessageDialog.setVisible(true);
    	    }
    	    
		} catch (Exception e) {
		    view.showWarningDialog(Constant.messages.getString("menu.file.savingSession.error"));	// ZAP: i18n
    	    log.error("error saving session file " + session.getFileName());
            log.error(e.getMessage(), e);
		}
	    
	}
	
	public void saveAsSession() {
		
	    Session session = model.getSession();

	    JFileChooser chooser = new JFileChooser(model.getOptionsParam().getUserDirectory());
	    // ZAP: set session name as file name proposal
	    File fileproposal = new File(session.getSessionName());
	    if (session.getFileName() != null && session.getFileName().trim().length() > 0) {
	    	// if there is already a file name, use it
	    	fileproposal = new File(session.getFileName());
	    }
		chooser.setSelectedFile(fileproposal);
	    chooser.setFileFilter(new FileFilter() {
	           @Override
	           public boolean accept(File file) {
	                if (file.isDirectory()) {
	                    return true;
	                } else if (file.isFile() && file.getName().endsWith(".session")) {
	                    return true;
	                }
	                return false;
	            }
	           @Override
	           public String getDescription() {
	        	   // ZAP: Rebrand
	               return Constant.messages.getString("file.format.zap.session");
	           }
	    });
		File file = null;
	    int rc = chooser.showSaveDialog(view.getMainFrame());
	    if(rc == JFileChooser.APPROVE_OPTION) {
    		file = chooser.getSelectedFile();
    		if (file == null) {
    			return;
    		}
            model.getOptionsParam().setUserDirectory(chooser.getCurrentDirectory());
    		String fileName = file.getAbsolutePath();
    		if (!fileName.endsWith(".session")) {
    		    fileName += ".session";
    		}
    		
    		try {
	    	    waitMessageDialog = view.getWaitMessageDialog(Constant.messages.getString("menu.file.savingSession"));	// ZAP: i18n
	    	    control.saveSession(fileName, this);
        	    log.info("save as session file " + session.getFileName());
        	    waitMessageDialog.setVisible(true);
    		} catch (Exception e) {
                log.error(e.getMessage(), e);
    		}
	    }
	}
	
	public void saveSnapshot() {
	    Session session = model.getSession();

	    JFileChooser chooser = new JFileChooser(model.getOptionsParam().getUserDirectory());
	    // ZAP: set session name as file name proposal
	    File fileproposal = new File(session.getSessionName());
	    if (session.getFileName() != null && session.getFileName().trim().length() > 0) {
		    String proposedFileName;
	    	// if there is already a file name, use it and add a timestamp
	    	proposedFileName = StringUtils.removeEnd(session.getFileName(), ".session");
	    	proposedFileName += "-" + dateFormat.format(new Date()) + ".session";
	    	fileproposal = new File(proposedFileName);
	    }
		chooser.setSelectedFile(fileproposal);
	    chooser.setFileFilter(new FileFilter() {
	           @Override
	           public boolean accept(File file) {
	                if (file.isDirectory()) {
	                    return true;
	                } else if (file.isFile() && file.getName().endsWith(".session")) {
	                    return true;
	                }
	                return false;
	            }
	           @Override
	           public String getDescription() {
	               return Constant.messages.getString("file.format.zap.session");
	           }
	    });
		File file = null;
	    int rc = chooser.showSaveDialog(view.getMainFrame());
	    if(rc == JFileChooser.APPROVE_OPTION) {
    		file = chooser.getSelectedFile();
    		if (file == null) {
    			return;
    		}
            model.getOptionsParam().setUserDirectory(chooser.getCurrentDirectory());
            String fileName = file.getAbsolutePath();
    		if (!fileName.endsWith(".session")) {
    		    fileName += ".session";
    		}
    		
    		try {
	    	    waitMessageDialog = view.getWaitMessageDialog(Constant.messages.getString("menu.file.savingSnapshot"));	// ZAP: i18n
	    	    control.snapshotSession(fileName, this);
        	    log.info("Snapshotting: " + session.getFileName() + " as " + fileName);
        	    waitMessageDialog.setVisible(true);
    		} catch (Exception e) {
                log.error(e.getMessage(), e);
    		}
	    }
	}
	
	private void setTitle() {
		StringBuilder strBuilder = new StringBuilder(model.getSession().getSessionName());
		if (!model.getSession().isNewState()) {
	        File file = new File(model.getSession().getFileName());
			strBuilder.append(" - ").append(file.getName().replaceAll(".session\\z", ""));
		}
		view.getMainFrame().setTitle(strBuilder.toString());
	}
	
	public void properties() {
		// ZAP: proper call of existing method
		View.getSingleton().showSessionDialog(model.getSession(), null);

	    // ZAP: Set the title consistently
	    setTitle();
//		view.getMainFrame().setTitle(Constant.PROGRAM_NAME + " " + Constant.PROGRAM_VERSION + " - " + model.getSession().getSessionName());
	}

    @Override
    public void sessionOpened(File file, Exception e) {
        if (e == null) {
            // ZAP: Removed the statement that called the method
            // ExtensionLoader.sessionChangedAllPlugin, now it's done in the
            // class Control.

            // ZAP: Set the title consistently
            setTitle();
            //view.getMainFrame().setTitle(file.getName().replaceAll(".session\\z","") + " - " + Constant.PROGRAM_NAME);
        } else {
            view.showWarningDialog(Constant.messages.getString("menu.file.openSession.errorFile"));
            if (file != null) {
                log.error("Error opening session file " + file.getAbsolutePath(), e);
            } else {
            	// File is null for table based sessions (ie non HSQLDB)
                log.error(e.getMessage(), e);
            }
        }

        if (waitMessageDialog != null) {
            waitMessageDialog.setVisible(false);
            waitMessageDialog = null;
        }
    }

    @Override
    public void sessionSaved(Exception e) {
        if (e == null) {
            // ZAP: Set the title consistently
            setTitle();
            //File file = new File(model.getSession().getFileName());
            //view.getMainFrame().setTitle(file.getName().replaceAll(".session\\z","") + " - " + Constant.PROGRAM_NAME);
        } else {
		    view.showWarningDialog(Constant.messages.getString("menu.file.savingSession.error"));	// ZAP: i18n
    	    log.error("error saving session file " + model.getSession().getFileName(), e);
            log.error(e.getMessage(), e);

        }
        
        if (waitMessageDialog != null) {
            waitMessageDialog.setVisible(false);
            waitMessageDialog = null;
        }

    }
    
	@Override
	public void sessionSnapshot(Exception e) {
        if (e != null) {
		    view.showWarningDialog(Constant.messages.getString("menu.file.snapshotSession.error"));	// ZAP: i18n
    	    log.error("error saving snapshot file " + model.getSession().getFileName(), e);
            log.error(e.getMessage(), e);
        }
        
        if (waitMessageDialog != null) {
            waitMessageDialog.setVisible(false);
            waitMessageDialog = null;
        }
	}

	/**
	 * Prompt the user to export a context
	 */
	public void importContext() {
		JFileChooser chooser = new JFileChooser(Constant.getContextsDir());
		File file = null;
	    chooser.setFileFilter(new FileFilter() {
	           @Override
	           public boolean accept(File file) {
	                if (file.isDirectory()) {
	                    return true;
	                } else if (file.isFile() && file.getName().endsWith(".context")) {
	                    return true;
	                }
	                return false;
	            }
	           @Override
	           public String getDescription() {
	               return Constant.messages.getString("file.format.zap.context");
	           }
	    });
	    
	    int rc = chooser.showOpenDialog(View.getSingleton().getMainFrame());
	    if(rc == JFileChooser.APPROVE_OPTION) {
			try {
	    		file = chooser.getSelectedFile();
	    		if (file == null || ! file.exists()) {
	    			return;
	    		}
	    		// Import the context
				Model.getSingleton().getSession().importContext(file);
				
				// Show the dialog
			    View.getSingleton().showSessionDialog(
			    		Model.getSingleton().getSession(), 
			    		Constant.messages.getString("context.list"), true);
				
			} catch (IllegalContextNameException e) {
				String detailError;
				if (e.getReason() == IllegalContextNameException.Reason.EMPTY_NAME) {
					detailError = Constant.messages.getString("context.error.name.empty");
				} else if (e.getReason() == IllegalContextNameException.Reason.DUPLICATED_NAME) {
					detailError = Constant.messages.getString("context.error.name.duplicated");
				} else {
					detailError = Constant.messages.getString("context.error.name.unknown");
				}
				View.getSingleton().showWarningDialog(
						MessageFormat.format(Constant.messages.getString("context.import.error"), detailError));
			} catch (Exception e1) {
				log.debug(e1.getMessage(), e1);
				View.getSingleton().showWarningDialog(MessageFormat.format(
						Constant.messages.getString("context.import.error"), e1.getMessage()));
			}
	    }
	}

	/**
	 * Prompt the user to export a context
	 */
	public void exportContext() {
		ContextExportDialog exportDialog = new ContextExportDialog(View.getSingleton().getMainFrame());
		exportDialog.setVisible(true);
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy