0001: /*
0002: * SSHTools - Java SSH2 API
0003: *
0004: * Copyright (C) 2002-2003 Lee David Painter and Contributors.
0005: *
0006: * Contributions made by:
0007: *
0008: * Brett Smith
0009: * Richard Pernavas
0010: * Erwin Bolwidt
0011: *
0012: * This program is free software; you can redistribute it and/or
0013: * modify it under the terms of the GNU General Public License
0014: * as published by the Free Software Foundation; either version 2
0015: * of the License, or (at your option) any later version.
0016: *
0017: * This program is distributed in the hope that it will be useful,
0018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0020: * GNU General Public License for more details.
0021: *
0022: * You should have received a copy of the GNU General Public License
0023: * along with this program; if not, write to the Free Software
0024: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0025: */
0026: package com.sshtools.common.ui;
0027:
0028: import com.sshtools.common.authentication.AuthenticationDialog;
0029: import com.sshtools.common.authentication.BannerDialog;
0030: import com.sshtools.common.authentication.KBIRequestHandlerDialog;
0031: import com.sshtools.common.authentication.PasswordAuthenticationDialog;
0032: import com.sshtools.common.authentication.PasswordChange;
0033: import com.sshtools.common.authentication.PublicKeyAuthenticationPrompt;
0034: import com.sshtools.common.automate.RemoteIdentification;
0035: import com.sshtools.common.automate.RemoteIdentificationException;
0036: import com.sshtools.common.automate.RemoteIdentificationFactory;
0037: import com.sshtools.common.configuration.InvalidProfileFileException;
0038: import com.sshtools.common.configuration.SshToolsConnectionProfile;
0039: import com.sshtools.common.hosts.DialogKnownHostsKeyVerification;
0040:
0041: import com.sshtools.j2ssh.SshClient;
0042: import com.sshtools.j2ssh.SshException;
0043: import com.sshtools.j2ssh.SshThread;
0044: import com.sshtools.j2ssh.agent.AgentAuthenticationClient;
0045: import com.sshtools.j2ssh.agent.AgentNotAvailableException;
0046: import com.sshtools.j2ssh.agent.SshAgentClient;
0047: import com.sshtools.j2ssh.authentication.AuthenticationProtocolState;
0048: import com.sshtools.j2ssh.authentication.KBIAuthenticationClient;
0049: import com.sshtools.j2ssh.authentication.PasswordAuthenticationClient;
0050: import com.sshtools.j2ssh.authentication.PublicKeyAuthenticationClient;
0051: import com.sshtools.j2ssh.authentication.SshAuthenticationClient;
0052: import com.sshtools.j2ssh.authentication.SshAuthenticationClientFactory;
0053: import com.sshtools.j2ssh.configuration.ConfigurationLoader;
0054: import com.sshtools.j2ssh.transport.AbstractKnownHostsKeyVerification;
0055: import com.sshtools.j2ssh.transport.HostKeyVerification;
0056: import com.sshtools.j2ssh.transport.InvalidHostFileException;
0057: import com.sshtools.j2ssh.transport.TransportProtocolException;
0058: import com.sshtools.j2ssh.transport.TransportProtocolState;
0059: import com.sshtools.j2ssh.transport.publickey.SshPublicKey;
0060:
0061: import org.apache.commons.logging.Log;
0062: import org.apache.commons.logging.LogFactory;
0063:
0064: import java.awt.Frame;
0065: import java.awt.LayoutManager;
0066:
0067: import java.io.File;
0068: import java.io.FilePermission;
0069: import java.io.IOException;
0070:
0071: import java.security.AccessControlException;
0072: import java.security.AccessController;
0073:
0074: import java.util.Comparator;
0075: import java.util.HashMap;
0076: import java.util.Iterator;
0077: import java.util.Map;
0078:
0079: import javax.swing.JFileChooser;
0080: import javax.swing.JOptionPane;
0081: import javax.swing.SwingConstants;
0082: import javax.swing.SwingUtilities;
0083: import javax.swing.UIManager;
0084: import javax.swing.filechooser.FileFilter;
0085:
0086: /**
0087: *
0088: *
0089: * @author $author$
0090: * @version $Revision: 1.24 $
0091: */
0092: public abstract class SshToolsApplicationClientPanel extends
0093: SshToolsApplicationPanel {
0094: /** */
0095: public final static String PREF_CONNECTION_FILE_DIRECTORY = "sshapps.connectionFile.directory";
0096:
0097: //
0098:
0099: /** */
0100: public final static int BANNER_TIMEOUT = 2000;
0101:
0102: /** */
0103: protected static AbstractKnownHostsKeyVerification ver;
0104:
0105: //
0106:
0107: /** */
0108: protected Log log = LogFactory
0109: .getLog(SshToolsApplicationClientPanel.class);
0110:
0111: /** */
0112: protected HostKeyVerification hostKeyVerification;
0113:
0114: /** */
0115: protected File currentConnectionFile;
0116:
0117: /** */
0118: protected boolean needSave;
0119:
0120: /** */
0121: protected SshToolsConnectionProfile currentConnectionProfile;
0122:
0123: /** */
0124: protected javax.swing.filechooser.FileFilter connectionFileFilter = new ConnectionFileFilter();
0125:
0126: /** */
0127: protected SshClient ssh;
0128:
0129: /**
0130: * Creates a new SshToolsApplicationClientPanel object.
0131: */
0132: public SshToolsApplicationClientPanel() {
0133: super ();
0134: }
0135:
0136: /**
0137: * Creates a new SshToolsApplicationClientPanel object.
0138: *
0139: * @param mgr
0140: */
0141: public SshToolsApplicationClientPanel(LayoutManager mgr) {
0142: super (mgr);
0143: }
0144:
0145: /**
0146: *
0147: *
0148: * @return
0149: */
0150: public abstract SshToolsConnectionTab[] getAdditionalConnectionTabs();
0151:
0152: /**
0153: *
0154: *
0155: * @return
0156: */
0157: public HostKeyVerification getHostKeyVerification() {
0158: return hostKeyVerification;
0159: }
0160:
0161: /**
0162: *
0163: *
0164: * @param hostKeyVerification
0165: */
0166: public void setHostHostVerification(
0167: HostKeyVerification hostKeyVerification) {
0168: this .hostKeyVerification = hostKeyVerification;
0169: }
0170:
0171: /**
0172: *
0173: *
0174: * @param application
0175: *
0176: * @throws SshToolsApplicationException
0177: */
0178: public void init(SshToolsApplication application)
0179: throws SshToolsApplicationException {
0180: super .init(application);
0181:
0182: try {
0183: //if (ver == null) {
0184: ver = new DialogKnownHostsKeyVerification(this );
0185:
0186: //}
0187: setHostHostVerification(ver);
0188:
0189: if (ver.isHostFileWriteable()) {
0190: application.addAdditionalOptionsTab(new HostsTab(ver));
0191: }
0192: } catch (InvalidHostFileException uhfe) {
0193: log.warn("Host key verification will be DISABLED.", uhfe);
0194: }
0195: }
0196:
0197: /**
0198: *
0199: */
0200: public void editConnection() {
0201: // Create a file chooser with the current directory set to the
0202: // application home
0203: JFileChooser fileDialog = new JFileChooser(PreferencesStore
0204: .get(PREF_CONNECTION_FILE_DIRECTORY, System
0205: .getProperty("sshtools.home", System
0206: .getProperty("user.home"))));
0207: fileDialog.setFileFilter(connectionFileFilter);
0208:
0209: // Show it
0210: int ret = fileDialog.showOpenDialog(this );
0211:
0212: // If we've approved the selection then process
0213: if (ret == fileDialog.APPROVE_OPTION) {
0214: PreferencesStore.put(PREF_CONNECTION_FILE_DIRECTORY,
0215: fileDialog.getCurrentDirectory().getAbsolutePath());
0216:
0217: // Get the file
0218: File f = fileDialog.getSelectedFile();
0219:
0220: // Load the profile
0221: SshToolsConnectionProfile p = new SshToolsConnectionProfile();
0222:
0223: try {
0224: p.open(f);
0225:
0226: if (editConnection(p)) {
0227: saveConnection(false, f, p);
0228: }
0229: } catch (IOException ioe) {
0230: showErrorMessage(this ,
0231: "Failed to load connection profile.", "Error",
0232: ioe);
0233: }
0234: }
0235: }
0236:
0237: /**
0238: *
0239: *
0240: * @param profile
0241: *
0242: * @return
0243: */
0244: public SshToolsConnectionProfile newConnectionProfile(
0245: SshToolsConnectionProfile profile) {
0246: return SshToolsConnectionPanel.showConnectionDialog(
0247: SshToolsApplicationClientPanel.this , profile,
0248: getAdditionalConnectionTabs());
0249: }
0250:
0251: /**
0252: *
0253: */
0254: public void open() {
0255: // Create a file chooser with the current directory set to the
0256: // application home
0257: String prefsDir = super .getApplication()
0258: .getApplicationPreferencesDirectory().getAbsolutePath();
0259: JFileChooser fileDialog = new JFileChooser(prefsDir);
0260: fileDialog.setFileFilter(connectionFileFilter);
0261:
0262: // Show it
0263: int ret = fileDialog.showOpenDialog(this );
0264:
0265: // If we've approved the selection then process
0266: if (ret == fileDialog.APPROVE_OPTION) {
0267: PreferencesStore.put(PREF_CONNECTION_FILE_DIRECTORY,
0268: fileDialog.getCurrentDirectory().getAbsolutePath());
0269:
0270: // Get the file
0271: File f = fileDialog.getSelectedFile();
0272: open(f);
0273: }
0274: }
0275:
0276: /**
0277: *
0278: *
0279: * @param f
0280: */
0281: public void open(File f) {
0282: log.debug("Opening connection file " + f);
0283:
0284: // Make sure a connection is not already open
0285: if (isConnected()) {
0286: Option optNew = new Option("New",
0287: "New create a new window", 'n');
0288: Option optClose = new Option("Close",
0289: "Close current connection", 'l');
0290: Option optCancel = new Option("Cancel",
0291: "Cancel the opening of this connection", 'c');
0292: OptionsDialog dialog = OptionsDialog
0293: .createOptionDialog(
0294: this ,
0295: new Option[] { optNew, optClose, optCancel },
0296: "You already have a connection open. Select\n"
0297: + "Close to close the current connection, New\n"
0298: + "to create a new terminal or Cancel to abort.",
0299: "Existing connection", optNew, null,
0300: UIManager.getIcon("OptionPane.warningIcon"));
0301: UIUtil.positionComponent(SwingConstants.CENTER, dialog);
0302: dialog.setVisible(true);
0303:
0304: Option opt = dialog.getSelectedOption();
0305:
0306: if ((opt == null) || (opt == optCancel)) {
0307: return;
0308: } else if (opt == optNew) {
0309: try {
0310: SshToolsApplicationContainer c = (SshToolsApplicationContainer) application
0311: .newContainer();
0312: ((SshToolsApplicationClientPanel) c
0313: .getApplicationPanel()).open(f);
0314:
0315: return;
0316: } catch (SshToolsApplicationException stae) {
0317: log.error(stae);
0318: }
0319: } else {
0320: closeConnection(true);
0321: }
0322: }
0323:
0324: // Save to MRU
0325: if (getApplication().getMRUModel() != null) {
0326: getApplication().getMRUModel().add(f);
0327: }
0328:
0329: // Make sure its not invalid
0330: if (f != null) {
0331: // Create a new connection properties object
0332: SshToolsConnectionProfile profile = new SshToolsConnectionProfile();
0333:
0334: try {
0335: // Open the file
0336: profile.open(f.getAbsolutePath());
0337: setNeedSave(false);
0338: currentConnectionFile = f;
0339: setContainerTitle(f);
0340:
0341: // Connect with the new details.
0342: connect(profile, false);
0343: } catch (InvalidProfileFileException fnfe) {
0344: showExceptionMessage(fnfe.getMessage(),
0345: "Open Connection");
0346: } catch (SshException e) {
0347: e.printStackTrace();
0348: showExceptionMessage("An unexpected error occured!",
0349: "Open Connection");
0350: }
0351: } else {
0352: showExceptionMessage("Invalid file specified",
0353: "Open Connection");
0354: }
0355: }
0356:
0357: /**
0358: *
0359: *
0360: * @param profile
0361: * @param newProfile
0362: */
0363: public void connect(final SshToolsConnectionProfile profile,
0364: final boolean newProfile) {
0365: // We need to connect
0366: ssh = new SshClient();
0367:
0368: // Set the current connection properties
0369: setCurrentConnectionProfile(profile);
0370:
0371: // We'll do the threading rather than j2ssh as we want to get errors
0372: Runnable r = new Runnable() {
0373: public void run() {
0374: // Update the status bar
0375: getStatusBar().setStatusText("Connecting");
0376: getStatusBar().setHost(
0377: getCurrentConnectionProfile().getHost(),
0378: getCurrentConnectionProfile().getPort());
0379: getStatusBar().setUser(
0380: getCurrentConnectionProfile().getUsername());
0381:
0382: //
0383: try {
0384: log.info("Connecting to "
0385: + getCurrentConnectionProfile().getHost()
0386: + " as "
0387: + getCurrentConnectionProfile()
0388: .getUsername());
0389: ssh
0390: .connect(
0391: getCurrentConnectionProfile(),
0392: (getHostKeyVerification() == null) ? new SinkHostKeyVerification()
0393: : getHostKeyVerification());
0394:
0395: // Set the remote id if we can find on
0396: try {
0397: RemoteIdentification rid = RemoteIdentificationFactory
0398: .getInstance(ssh.getServerId(), ssh
0399: .getConnectionProperties()
0400: .getHost());
0401: getStatusBar().setRemoteId(
0402: rid.getName(ssh.getServerId()));
0403: } catch (RemoteIdentificationException ex) {
0404: getStatusBar().setRemoteId("Unknown");
0405: }
0406:
0407: if (postConnection()) {
0408: if (!authenticateUser(newProfile)) {
0409: closeConnection(false);
0410: } else {
0411: setAvailableActions();
0412: }
0413: }
0414: } catch (IOException sshe) {
0415: ssh = null;
0416: showExceptionMessage("Connection Error",
0417: "Could not establish a connection to host: \n\n "
0418: + sshe.getMessage());
0419: SshToolsApplicationClientPanel.this
0420: .closeConnection(false);
0421: } catch (SecurityException se) {
0422: ssh = null;
0423: showErrorMessage(
0424: SshToolsApplicationClientPanel.this ,
0425: "Error", se);
0426: SshToolsApplicationClientPanel.this
0427: .closeConnection(false);
0428: }
0429: }
0430: };
0431:
0432: Thread thread = new SshThread(r, application
0433: .getApplicationName()
0434: + " connection", true);
0435: thread.start();
0436: }
0437:
0438: /**
0439: *
0440: *
0441: * @param ssh
0442: * @param profile
0443: *
0444: * @throws IOException
0445: */
0446: public void connect(SshClient ssh, SshToolsConnectionProfile profile)
0447: throws IOException {
0448: this .ssh = ssh;
0449:
0450: if (!ssh.isAuthenticated()) {
0451: authenticateUser(false);
0452: }
0453:
0454: // Set the current connection properties
0455: setCurrentConnectionProfile(profile);
0456: authenticationComplete(false);
0457: }
0458:
0459: /**
0460: *
0461: *
0462: * @param newProfile
0463: *
0464: * @return
0465: *
0466: * @throws IOException
0467: */
0468: protected boolean authenticateUser(boolean newProfile)
0469: throws IOException {
0470: // We should now authenticate
0471: int result = AuthenticationProtocolState.READY;
0472:
0473: // Our authenticated flag
0474: boolean authenticated = false;
0475:
0476: // Get the supported authentication methods
0477: java.util.List supported = SshAuthenticationClientFactory
0478: .getSupportedMethods();
0479:
0480: // If the server supports public key lets look for an agent and try
0481: // some of his keys
0482: if (supported.contains("publickey")) {
0483: if (System.getProperty("sshtools.agent") != null) {
0484: try {
0485: SshAgentClient agent = SshAgentClient
0486: .connectLocalAgent("SSHTerm", System
0487: .getProperty("sshtools.agent") /*, 5*/);
0488: AgentAuthenticationClient aac = new AgentAuthenticationClient();
0489: aac.setAgent(agent);
0490: aac.setUsername(getCurrentConnectionProfile()
0491: .getUsername());
0492: result = ssh.authenticate(aac);
0493: agent.close();
0494: } catch (AgentNotAvailableException ex) {
0495: log
0496: .info("No agent was available for authentication");
0497:
0498: // Just continue
0499: }
0500:
0501: if (result == AuthenticationProtocolState.COMPLETE) {
0502: authenticationComplete(newProfile);
0503:
0504: return true;
0505: }
0506: }
0507: }
0508:
0509: // Create a list for display that will contain only the
0510: // supported and available methods
0511: java.util.List display = new java.util.ArrayList();
0512:
0513: // Get the available methods
0514: java.util.List auths = null;
0515: auths = ssh
0516: .getAvailableAuthMethods(getCurrentConnectionProfile()
0517: .getUsername());
0518:
0519: // Did we receive a banner from the remote computer
0520: final String banner = ssh
0521: .getAuthenticationBanner(BANNER_TIMEOUT);
0522:
0523: if (banner != null) {
0524: if (!banner.trim().equals("")) {
0525: try {
0526: SwingUtilities.invokeAndWait(new Runnable() {
0527: public void run() {
0528: BannerDialog
0529: .showBannerDialog(
0530: SshToolsApplicationClientPanel.this ,
0531: banner);
0532: }
0533: });
0534: } catch (Exception e) {
0535: log
0536: .error(
0537: "Failed to invoke and wait on BannerDialog",
0538: e);
0539: }
0540: }
0541: }
0542:
0543: // Are there any authentication methods within the properties file?
0544: // Iterate through selecting only the supported and available
0545: Iterator it = supported.iterator();
0546:
0547: while (it.hasNext() && !authenticated) {
0548: Object obj = it.next();
0549:
0550: if (auths.contains(obj)) {
0551: display.add(obj);
0552: }
0553: }
0554:
0555: // First look to see if we have any authenticaiton methods available
0556: // in the profile properties object as this will overide a manual selection
0557: java.util.Map authMethods = (Map) ((HashMap) getCurrentConnectionProfile()
0558: .getAuthenticationMethods()).clone();
0559: it = authMethods.entrySet().iterator();
0560:
0561: //Iterator it2 = null;
0562: java.util.List selected;
0563:
0564: // Loop until the user either cancels or completes
0565: boolean completed = false;
0566: SshAuthenticationClient auth;
0567: Map.Entry entry;
0568: String msg = null;
0569:
0570: while (!completed
0571: && (ssh.getConnectionState().getValue() != TransportProtocolState.DISCONNECTED)) {
0572: auth = null;
0573:
0574: // Select an authentication method from the properties file or
0575: // prompt the user to choose
0576: if (it.hasNext()) {
0577: Object obj = it.next();
0578:
0579: if (obj instanceof Map.Entry) {
0580: entry = (Map.Entry) obj;
0581: auth = (SshAuthenticationClient) entry.getValue();
0582: } else if (obj instanceof String) {
0583: auth = SshAuthenticationClientFactory
0584: .newInstance((String) obj);
0585: auth.setUsername(getCurrentConnectionProfile()
0586: .getUsername());
0587: } else {
0588: closeConnection(true);
0589: throw new IOException(
0590: "Iterator of Map or List of String expected");
0591: }
0592: } else {
0593: selected = AuthenticationDialog
0594: .showAuthenticationDialog(this , display,
0595: ((msg == null) ? "" : msg));
0596:
0597: if (selected.size() > 0) {
0598: it = selected.iterator();
0599: } else {
0600: closeConnection(true);
0601:
0602: return false;
0603: }
0604: }
0605:
0606: if (auth != null) {
0607: // The password authentication client can act upon requests to change the password
0608:
0609: /* if (auth instanceof PasswordAuthenticationClient) {
0610: PasswordAuthenticationDialog dialog = new PasswordAuthenticationDialog(SshTerminalPanel.this);
0611: ((PasswordAuthenticationClient) auth).setAuthenticationPrompt(dialog);
0612: ( (PasswordAuthenticationClient) auth)
0613: .setPasswordChangePrompt(PasswordChange.getInstance());
0614: PasswordChange.getInstance().setParentComponent(
0615: SshTerminalPanel.this);
0616: }*/
0617:
0618: // Show the implementations dialog
0619: // if(auth.showAuthenticationDialog()) {
0620: // Authentication with the details supplied
0621: result = showAuthenticationPrompt(auth); //ssh.authenticate(auth);
0622:
0623: if (result == AuthenticationProtocolState.FAILED) {
0624: msg = auth.getMethodName()
0625: + " authentication failed, try again?";
0626: }
0627:
0628: // If the result returned partial success then continue
0629: if (result == AuthenticationProtocolState.PARTIAL) {
0630: // We succeeded so add to the connections authenticaiton
0631: // list and continue on to the next one
0632: getCurrentConnectionProfile()
0633: .addAuthenticationMethod(auth);
0634: msg = auth.getMethodName()
0635: + " authentication succeeded but another is required";
0636: }
0637:
0638: if (result == AuthenticationProtocolState.COMPLETE) {
0639: authenticated = true;
0640:
0641: //If successfull add to the connections list so we can save later
0642: getCurrentConnectionProfile()
0643: .addAuthenticationMethod(auth);
0644:
0645: // Set the completed flag
0646: completed = true;
0647: authenticationComplete(newProfile);
0648: }
0649:
0650: if (result == AuthenticationProtocolState.CANCELLED) {
0651: ssh.disconnect();
0652:
0653: return false;
0654: }
0655:
0656: // }
0657: // else {
0658: // User has cancelled the authenticaiton
0659: // closeConnection(true);
0660: // return false;
0661: // }
0662: }
0663:
0664: // end of if
0665: }
0666:
0667: // end of while
0668: return authenticated;
0669: }
0670:
0671: /**
0672: *
0673: *
0674: * @param instance
0675: *
0676: * @return
0677: *
0678: * @throws IOException
0679: */
0680: protected int showAuthenticationPrompt(
0681: SshAuthenticationClient instance) throws IOException {
0682: instance.setUsername(getCurrentConnectionProfile()
0683: .getUsername());
0684:
0685: if (instance instanceof PasswordAuthenticationClient) {
0686: PasswordAuthenticationDialog dialog = new PasswordAuthenticationDialog(
0687: (Frame) SwingUtilities.getAncestorOfClass(
0688: Frame.class,
0689: SshToolsApplicationClientPanel.this ));
0690: instance.setAuthenticationPrompt(dialog);
0691: ((PasswordAuthenticationClient) instance)
0692: .setPasswordChangePrompt(PasswordChange
0693: .getInstance());
0694: PasswordChange.getInstance().setParentComponent(
0695: SshToolsApplicationClientPanel.this );
0696: } else if (instance instanceof PublicKeyAuthenticationClient) {
0697: PublicKeyAuthenticationPrompt prompt = new PublicKeyAuthenticationPrompt(
0698: SshToolsApplicationClientPanel.this );
0699: instance.setAuthenticationPrompt(prompt);
0700: } else if (instance instanceof KBIAuthenticationClient) {
0701: KBIAuthenticationClient kbi = new KBIAuthenticationClient();
0702: ((KBIAuthenticationClient) instance)
0703: .setKBIRequestHandler(new KBIRequestHandlerDialog(
0704: (Frame) SwingUtilities
0705: .getAncestorOfClass(
0706: Frame.class,
0707: SshToolsApplicationClientPanel.this )));
0708: }
0709:
0710: return ssh.authenticate(instance);
0711: }
0712:
0713: /**
0714: *
0715: *
0716: * @return
0717: */
0718: public abstract boolean postConnection();
0719:
0720: /**
0721: *
0722: *
0723: * @param newProfile
0724: *
0725: * @throws SshException
0726: * @throws IOException
0727: */
0728: public abstract void authenticationComplete(boolean newProfile)
0729: throws SshException, IOException;
0730:
0731: /**
0732: *
0733: *
0734: * @param file
0735: */
0736: public void setContainerTitle(File file) {
0737: String verString = ConfigurationLoader.getVersionString(
0738: application.getApplicationName(), application
0739: .getApplicationVersion());
0740:
0741: if (container != null) {
0742: container.setContainerTitle((file == null) ? verString
0743: : (verString + " [" + file.getName() + "]"));
0744: }
0745: }
0746:
0747: /**
0748: *
0749: *
0750: * @param needSave
0751: */
0752: public void setNeedSave(boolean needSave) {
0753: if (needSave != this .needSave) {
0754: this .needSave = needSave;
0755: setAvailableActions();
0756: }
0757: }
0758:
0759: /**
0760: *
0761: *
0762: * @param file
0763: */
0764: public void setCurrentConnectionFile(File file) {
0765: currentConnectionFile = file;
0766: }
0767:
0768: /**
0769: *
0770: *
0771: * @return
0772: */
0773: public File getCurrentConnectionFile() {
0774: return currentConnectionFile;
0775: }
0776:
0777: /**
0778: *
0779: *
0780: * @param profile
0781: */
0782: public void setCurrentConnectionProfile(
0783: SshToolsConnectionProfile profile) {
0784: currentConnectionProfile = profile;
0785: }
0786:
0787: /**
0788: *
0789: *
0790: * @return
0791: */
0792: public SshToolsConnectionProfile getCurrentConnectionProfile() {
0793: return currentConnectionProfile;
0794: }
0795:
0796: /**
0797: *
0798: *
0799: * @return
0800: */
0801: public boolean isNeedSave() {
0802: return needSave;
0803: }
0804:
0805: /**
0806: *
0807: *
0808: * @return
0809: */
0810: public boolean isConnected() {
0811: return (ssh != null) && ssh.isConnected();
0812: }
0813:
0814: /**
0815: *
0816: *
0817: * @throws SshException
0818: */
0819: public void connect() throws SshException {
0820: if (getCurrentConnectionProfile() == null) {
0821: throw new SshException(
0822: "Can't connect, no connection profile have been set.");
0823: }
0824:
0825: // There isn't anywhere to store this setting yet
0826: connect(getCurrentConnectionProfile(), false);
0827: }
0828:
0829: /**
0830: *
0831: *
0832: * @param disconnect
0833: */
0834: public void closeConnection(boolean disconnect) {
0835: //
0836: if (isNeedSave()) {
0837: // Only allow saving of files if allowed by the security manager
0838: try {
0839: if (System.getSecurityManager() != null) {
0840: AccessController
0841: .checkPermission(new FilePermission(
0842: "<<ALL FILES>>", "write"));
0843:
0844: if (JOptionPane
0845: .showConfirmDialog(
0846: this ,
0847: "You have unsaved changes to the connection "
0848: + ((currentConnectionFile == null) ? "<Untitled>"
0849: : currentConnectionFile
0850: .getName())
0851: + ".\nDo you want to save the changes now?",
0852: "Unsaved changes",
0853: JOptionPane.YES_NO_OPTION,
0854: JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION) {
0855: saveConnection(false,
0856: getCurrentConnectionFile(),
0857: getCurrentConnectionProfile());
0858: setNeedSave(false);
0859: }
0860: }
0861: } catch (AccessControlException ace) {
0862: log
0863: .warn("Changes made to connection, but security manager won't allow saving of files.");
0864: }
0865: }
0866:
0867: setCurrentConnectionFile(null);
0868: }
0869:
0870: /**
0871: *
0872: *
0873: * @return
0874: */
0875: protected boolean allowConnectionSettingsEditing() {
0876: return true;
0877: }
0878:
0879: /**
0880: *
0881: *
0882: * @param profile
0883: *
0884: * @return
0885: */
0886: public boolean editConnection(SshToolsConnectionProfile profile) {
0887: final SshToolsConnectionPanel panel = new SshToolsConnectionPanel(
0888: allowConnectionSettingsEditing());
0889: SshToolsConnectionTab[] tabs = getAdditionalConnectionTabs();
0890:
0891: for (int i = 0; (tabs != null) && (i < tabs.length); i++) {
0892: tabs[i].setConnectionProfile(profile);
0893: panel.addTab(tabs[i]);
0894: }
0895:
0896: panel.setConnectionProfile(profile);
0897:
0898: final Option ok = new Option("Ok",
0899: "Apply the settings and close this dialog", 'o');
0900: final Option cancel = new Option("Cancel",
0901: "Close this dialog without applying the settings", 'c');
0902: OptionCallback callback = new OptionCallback() {
0903: public boolean canClose(OptionsDialog dialog, Option option) {
0904: if (option == ok) {
0905: return panel.validateTabs();
0906: }
0907:
0908: return true;
0909: }
0910: };
0911:
0912: OptionsDialog od = OptionsDialog.createOptionDialog(
0913: SshToolsApplicationClientPanel.this , new Option[] { ok,
0914: cancel }, panel, "Connection Settings", ok,
0915: callback, null);
0916: od.pack();
0917: UIUtil.positionComponent(SwingConstants.CENTER, od);
0918: od.setVisible(true);
0919:
0920: if (od.getSelectedOption() == ok) {
0921: panel.applyTabs();
0922:
0923: if (profile == getCurrentConnectionProfile()) {
0924: setNeedSave(true);
0925: }
0926:
0927: return true;
0928: }
0929:
0930: return false;
0931: }
0932:
0933: /**
0934: *
0935: *
0936: * @param saveAs
0937: * @param file
0938: * @param profile
0939: *
0940: * @return
0941: */
0942: public File saveConnection(boolean saveAs, File file,
0943: SshToolsConnectionProfile profile) {
0944: if (profile != null) {
0945: if ((file == null) || saveAs) {
0946: String prefsDir = super .getApplication()
0947: .getApplicationPreferencesDirectory()
0948: .getAbsolutePath();
0949: JFileChooser fileDialog = new JFileChooser(prefsDir);
0950: fileDialog.setFileFilter(connectionFileFilter);
0951:
0952: int ret = fileDialog.showSaveDialog(this );
0953:
0954: if (ret == fileDialog.CANCEL_OPTION) {
0955: return null;
0956: }
0957:
0958: file = fileDialog.getSelectedFile();
0959:
0960: if (!file.getName().toLowerCase().endsWith(".xml")) {
0961: file = new File(file.getAbsolutePath() + ".xml");
0962: }
0963: }
0964:
0965: try {
0966: if (saveAs && file.exists()) {
0967: if (JOptionPane.showConfirmDialog(this ,
0968: "File already exists. Are you sure?",
0969: "File exists", JOptionPane.YES_NO_OPTION,
0970: JOptionPane.WARNING_MESSAGE) == JOptionPane.NO_OPTION) {
0971: return null;
0972: }
0973: }
0974:
0975: // Check to make sure its valid
0976: if (file != null) {
0977: // Save the connection details to file
0978: log.debug("Saving connection to "
0979: + file.getAbsolutePath());
0980: profile.save(file.getAbsolutePath());
0981:
0982: if (profile == getCurrentConnectionProfile()) {
0983: log
0984: .debug("Current connection saved, disabling save action.");
0985: setNeedSave(false);
0986: }
0987:
0988: return file;
0989: } else {
0990: showExceptionMessage(
0991: "The file specified is invalid!",
0992: "Save Connection");
0993: }
0994: } catch (InvalidProfileFileException e) {
0995: showExceptionMessage(e.getMessage(), "Save Connection");
0996: }
0997: }
0998:
0999: return null;
1000: }
1001:
1002: public static class ActionMenu implements Comparable {
1003: int weight;
1004: int mnemonic;
1005: String name;
1006: String displayName;
1007:
1008: public ActionMenu(String name, String displayName,
1009: int mnemonic, int weight) {
1010: this .name = name;
1011: this .displayName = displayName;
1012: this .mnemonic = mnemonic;
1013: this .weight = weight;
1014: }
1015:
1016: public int compareTo(Object o) {
1017: int i = new Integer(weight).compareTo(new Integer(
1018: ((ActionMenu) o).weight));
1019:
1020: return (i == 0) ? displayName
1021: .compareTo(((ActionMenu) o).displayName) : i;
1022: }
1023: }
1024:
1025: class ToolBarActionComparator implements Comparator {
1026: public int compare(Object o1, Object o2) {
1027: int i = ((Integer) ((StandardAction) o1)
1028: .getValue(StandardAction.TOOLBAR_GROUP))
1029: .compareTo((Integer) ((StandardAction) o2)
1030: .getValue(StandardAction.TOOLBAR_GROUP));
1031:
1032: return (i == 0) ? ((Integer) ((StandardAction) o1)
1033: .getValue(StandardAction.TOOLBAR_WEIGHT))
1034: .compareTo((Integer) ((StandardAction) o2)
1035: .getValue(StandardAction.TOOLBAR_WEIGHT))
1036: : i;
1037: }
1038: }
1039:
1040: class MenuItemActionComparator implements Comparator {
1041: public int compare(Object o1, Object o2) {
1042: int i = ((Integer) ((StandardAction) o1)
1043: .getValue(StandardAction.MENU_ITEM_GROUP))
1044: .compareTo((Integer) ((StandardAction) o2)
1045: .getValue(StandardAction.MENU_ITEM_GROUP));
1046:
1047: return (i == 0) ? ((Integer) ((StandardAction) o1)
1048: .getValue(StandardAction.MENU_ITEM_WEIGHT))
1049: .compareTo((Integer) ((StandardAction) o2)
1050: .getValue(StandardAction.MENU_ITEM_WEIGHT))
1051: : i;
1052: }
1053: }
1054:
1055: class ConnectionFileFilter extends
1056: javax.swing.filechooser.FileFilter {
1057: public boolean accept(File f) {
1058: return f.isDirectory()
1059: || f.getName().toLowerCase().endsWith(".xml");
1060: }
1061:
1062: public String getDescription() {
1063: return "Connection files (*.xml)";
1064: }
1065: }
1066:
1067: class SinkHostKeyVerification implements HostKeyVerification {
1068: public boolean verifyHost(String host, SshPublicKey pk)
1069: throws TransportProtocolException {
1070: log.warn("Accepting host " + host
1071: + " as host key verification is disabled.");
1072:
1073: return true;
1074: }
1075: }
1076: }
|