//***************************************************************************** //* //* (c) Copyright 2002. Glub Tech, Incorporated. All Rights Reserved. //* //* $Id: ConnectCommand.java 133 2009-12-11 08:44:22Z gary $ //* //***************************************************************************** package com.glub.secureftp.client.gui; import com.glub.secureftp.client.framework.*; import com.glub.secureftp.bean.*; import com.glub.util.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import javax.swing.*; public class ConnectCommand extends LocalCommand { private static MakingConnectionDialog makingConnectionDialog = null; public ConnectCommand() { super("connect", CommandID.CONNECT_COMMAND_ID, 1, 1, "bookmark", "connect to bookmark"); } public SecureFTPError doIt() throws CommandException { SecureFTPError result = super.doIt(); Bookmark book = (Bookmark)getArgs().get( 0 ); FTPSession session = FTPSessionManager.getInstance().getCurrentSession(); ConnectThread ct = new ConnectThread( book, session ); ct.start(); makingConnectionDialog = new MakingConnectionDialog( SecureFTP.getBaseFrame(), ct ); return result; } public static MakingConnectionDialog getMakingConnectionDialog() { return makingConnectionDialog; } public static void disposeDialog() { makingConnectionDialog = null; } } class ConnectThread extends Thread { private static final String classPath = "ConnectThread."; private Bookmark book = null; private FTPSession session = null; private boolean tryingToConnect = true; private static final int MAX_ATTEMPTS = 3; private JTextArea ta = new JTextArea( 4, 20 ); public ConnectThread( Bookmark book, FTPSession session ) { super(); this.book = book; this.session = session; } public void run() { FTP bean = null; ta.addMouseListener( new MouseAdapter() { public void mouseReleased( MouseEvent e ) { LogPopupMenu popupMenu = new LogPopupMenu( ta ); int macContextMask = MouseEvent.CTRL_DOWN_MASK; int unixContextMask = MouseEvent.META_DOWN_MASK; int sysContextMask = Util.isMacOS() ? macContextMask : unixContextMask; if ( e.isPopupTrigger() ) { popupMenu.show( e.getComponent(), e.getX(), e.getY() ); } else if ( !Util.isWindows() && ((e.getModifiersEx() & macContextMask) == sysContextMask || (e.getModifiersEx() & unixContextMask) == sysContextMask || 4 == e.getModifiers()) ) { popupMenu.show( e.getComponent(), e.getX(), e.getY() ); } } } ); LogStream ls = new LogStream( new ByteArrayOutputStream(), ta ); session.setOutputStream( ls ); SecureFTP.getBaseFrame().setCursor( new Cursor(Cursor.WAIT_CURSOR) ); debug( "Connection type: " + session.getSecurityMode() ); if ( FTPSession.IMPLICIT_SSL == session.getSecurityMode() ) { bean = new SSLFTP( session.getCertHandler(), session.getHostName(), session.getPort(), session.getKeyStoreFile(), null, SSLFTP.IMPLICIT_CONNECTION, session.getOutputStream(), session.getOutputStream() ); } else if ( FTPSession.EXPLICIT_SSL == session.getSecurityMode() ) { bean = new SSLFTP( session.getCertHandler(), session.getHostName(), session.getPort(), session.getKeyStoreFile(), null, SSLFTP.EXPLICIT_CONNECTION, session.getOutputStream(), session.getOutputStream() ); } else { bean = new FTP( session.getHostName(), session.getPort(), session.getOutputStream(), session.getOutputStream() ); } if ( session.usesProxy() ) { bean.setSocksVProxy( Client.getSocksHostName(), Client.getSocksPort(), Client.getSocksUserName(), Client.getSocksPassword() ); } short connType = book.isPassiveConnection() ? FTP.PASSIVE_CONNECTION_TYPE : FTP.ACTIVE_CONNECTION_TYPE; bean.setConnectionType( connType ); bean.forcePasvToUseControlIP( Client.forcePasvControlIP() ); session.setFTPBean( bean ); // just to make sure we don't try forever int connectionAttempts = 0; do { connect(); connectionAttempts++; } while( tryingToConnect && connectionAttempts <= MAX_ATTEMPTS ); } public void connect() { Client.getMenus().disableMenuBar(); Client.getToolBar().disableToolBar(); boolean successfulConnect = false; boolean loginFailed = false; FTP bean = session.getFTPBean(); String hostName = session.getHostName(); try { debug( "Connection attempt begun" ); if ( session.isSecure() ) { // set the client cert if available setClientCert( (SSLFTP)bean ); ((SSLFTP)bean).connect( book.isDataEncrypted() ); } else { bean.connect(); } tryingToConnect = false; debug( "Connected" ); if ( isInterrupted() ) { debug( "Operation cancelled" ); return; } int loginAttempts = 1; if ( session.getUserName().length() == 0 ) { if ( !AuthenticationDialog.showDialog(SecureFTP.getBaseFrame(), session) ) { loginAttempts = MAX_ATTEMPTS + 1; } } if ( isInterrupted() ) { debug( "Operation cancelled" ); return; } do { if ( isInterrupted() ) { debug( "Operation cancelled" ); return; } try { debug( "Logging in" ); bean.login( session.getUserName(), session.getPassword() ); if ( isInterrupted() ) { debug( "Operation cancelled" ); return; } debug( "Logged in" ); loginFailed = false; } catch ( IllegalArgumentException iae ) { debug( iae.getMessage() ); boolean infoChanged = false; if ( loginAttempts <= MAX_ATTEMPTS ) { infoChanged = AuthenticationDialog.showDialog( SecureFTP.getBaseFrame(), session ); } if ( !infoChanged ) { loginAttempts = MAX_ATTEMPTS + 1; loginFailed = true; } else { loginAttempts++; } } catch ( FTPBadLoginException fble ) { debug( fble.getMessage() ); boolean infoChanged = false; if ( loginAttempts <= MAX_ATTEMPTS ) { infoChanged = AuthenticationDialog.showDialog( SecureFTP.getBaseFrame(), session ); } if ( !infoChanged ) { loginAttempts = MAX_ATTEMPTS + 1; loginFailed = true; } else { loginAttempts++; } } catch ( FTPNeedPasswordException fnpe ) { debug( fnpe.getMessage() ); boolean infoChanged = false; if ( loginAttempts <= MAX_ATTEMPTS ) { infoChanged = AuthenticationDialog.showDialog( SecureFTP.getBaseFrame(), session ); } if ( !infoChanged ) { loginAttempts = MAX_ATTEMPTS + 1; loginFailed = true; } else { loginAttempts++; } } catch ( FTPException fe ) { debug( fe.getMessage() ); loginAttempts = MAX_ATTEMPTS + 1; loginFailed = true; } } while ( bean.isConnected() && !bean.isLoggedIn() && !loginFailed ); if ( isInterrupted() ) { debug( "Operation cancelled" ); return; } if ( bean.isConnected() && bean.isLoggedIn() ) { successfulConnect = true; } } catch ( UnknownHostException uhe ) { LString lmsg = new LString( classPath + "unknownHost", "[^0]: unknown host" ); lmsg.replace( 0, uhe.getMessage() ); ErrorDialog.showDialog( new LString(classPath + "connectionFailed.dialogTitle", "Connection Failed"), lmsg ); tryingToConnect = false; } catch ( IOException ioe ) { LString lmsg = new LString(classPath + "connectionFailed1", "Connection failed: [^0]"); lmsg.replace( 0, ioe.getMessage() ); ErrorDialog.showDialog( new LString(classPath + "connectionFailed.dialogTitle", "Connection Failed"), lmsg ); tryingToConnect = false; } catch ( FTPPolicyRestrictionException fpre ) { boolean tryAgain = tryAuthSSL(); if ( tryAgain ) { return; } } catch ( FTPAuthNotSupportedException fanse ) { boolean tryAgain = tryAuthSSL(); if ( tryAgain ) { return; } } catch ( FTPException ce ) { LString lmsg = new LString(classPath + "connectionFailed2", "[^0]: connection failed"); if ( null != hostName ) { lmsg.replace( 0, hostName ); } else { lmsg.replace( 0, "" ); } ErrorDialog.showDialog( new LString(classPath + "connectionFailed.dialogTitle", "Connection Failed"), lmsg ); tryingToConnect = false; } if ( isInterrupted() ) { debug( "Operation cancelled" ); return; } if ( successfulConnect ) { debug( "Connection successful" ); if ( SecureFTP.forceEncrypt && session.isSecure() ) { try { ((SSLFTP)bean).forceDataEncryptionOn( true ); } catch ( FTPException fe ) { debug( fe.getMessage() ); } } if ( isInterrupted() ) { debug( "Operation cancelled" ); return; } if ( session.useCCC() && session.isSecure() ) { LString lmsg = new LString(classPath + "cccNotSupported", "Clear Command Channel request not supported by server."); try { ((SSLFTP)bean).setClearCommandChannel(); } catch ( FTPException fe ) { ErrorDialog.showDialog( new LString(classPath + "connectionFailed.dialogTitle", "Connection Failed"), lmsg ); successfulConnect = false; } catch ( IOException ioe ) { ErrorDialog.showDialog( new LString(classPath + "connectionFailed.dialogTitle", "Connection Failed"), lmsg ); successfulConnect = false; } } if ( isInterrupted() ) { debug( "Operation cancelled" ); return; } try { if ((System.getProperty("file.encoding") != null && System.getProperty("file.encoding").toLowerCase().equals("utf8")) || (Client.getEncoding() != null && Client.getEncoding().toLowerCase().equals("utf8"))) { session.getFTPBean().setSendCmdStream(null); session.getFTPBean().setRecvCmdStream(null); bean.setStringDataAsUTF8( true ); session.getFTPBean().setSendCmdStream(session.getOutputStream()); session.getFTPBean().setRecvCmdStream(session.getOutputStream()); } } catch ( Exception e ) {} if ( isInterrupted() ) { debug( "Operation cancelled" ); return; } MakingConnectionDialog mcd = ConnectCommand.getMakingConnectionDialog(); if ( null != mcd ) { mcd.dispose(); } SecureFTP.getBaseFrame().setCursor( new Cursor(Cursor.DEFAULT_CURSOR) ); if ( successfulConnect ) { session.setTransferRestartable( bean.isTransferRestartable() ); boolean buildComboBox = true; if ( book.getRemoteFolder() != null && book.getRemoteFolder().length() > 0 ) { buildComboBox = false; } Client.getRemoteView().addConnection( session, ta, buildComboBox ); int transferMode = Client.getTransferMode(); Command transferModeCmd = null; switch( transferMode ) { case FTP.BINARY_TRANSFER_MODE: transferModeCmd = new BinaryXferCommand(); break; case FTP.ASCII_TRANSFER_MODE: transferModeCmd = new AsciiXferCommand(); break; case FTP.AUTO_TRANSFER_MODE: default: transferModeCmd = new AutoXferCommand(); break; } SecureFTP.getCommandDispatcher().fireCommand( this, transferModeCmd ); if ( Client.useModeZCompression() ) { try { bean.modeZ(); } catch ( FTPException fe ) { } } if ( book.getLocalFolder() != null && book.getLocalFolder().length() > 0 ) { File newDir = new File( book.getLocalFolder() ); Client.getLocalView().changeDirectory( newDir ); } if ( book.getRemoteFolder() != null && book.getRemoteFolder().length() > 0 ) { RemoteFile newDir = new RemoteFile( book.getRemoteFolder() ); ((RemotePanel)session.getRemoteUI()).changeDirectory( newDir, false ); } ((RemotePanel)session.getRemoteUI()).setFocus(); } else { FTPSessionManager.getInstance().removeCurrentSession(); } } else { SecureFTP.getBaseFrame().setCursor( new Cursor(Cursor.DEFAULT_CURSOR) ); LString lmsg = new LString(classPath + "loginFailed", "[^0]: login failed"); if ( null != hostName ) { lmsg.replace( 0, hostName ); } else { lmsg.replace( 0, "" ); } if ( loginFailed ) { ErrorDialog.showDialog( new LString(classPath + "loginFailed.dialogTitle", "Login Failed"), lmsg ); } tryingToConnect = false; FTPSessionManager.getInstance().removeCurrentSession(); } // make the dialog go away! MakingConnectionDialog mcd = ConnectCommand.getMakingConnectionDialog(); if ( null != mcd ) { mcd.dispose(); } SecureFTP.getBaseFrame().setCursor( new Cursor(Cursor.DEFAULT_CURSOR) ); Client.getMenus().enableMenuBar(); Client.getToolBar().enableToolBar(); } public void debug( String msg ) { if ( session.isDebugOn() ) System.out.println( msg ); } protected boolean tryAuthSSL() { boolean tryAgain = false; FTP bean = session.getFTPBean(); String hostName = session.getHostName(); try { bean.logout(); } catch ( Exception e ) {} if ( session.isSecure() && ((SSLFTP)bean).getAuthType().equals("TLS") ) { // try AUTH SSL before giving up ((SSLFTP)bean).setAuthType( "SSL" ); tryAgain = true; } else if ( session.isSecure() ) { // try insecure connection String msg = LString.getString( classPath + "makeInsecureConnection", "A secure connection (explicit SSL) could not be established.\n" + "Do you want to continue with an insecure connection?" ); String[] options = { LString.getString("Common.button.yes", "Yes"), LString.getString("Common.button.no", "No") }; int result = JOptionPane.showOptionDialog( SecureFTP.getBaseFrame(), msg, LString.getString(classPath + "connectionFailed.dialogTitle", "Connection Failed"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]); tryAgain = ( JOptionPane.YES_OPTION == result ); if ( tryAgain ) { bean = new FTP( session.getHostName(), session.getPort(), session.getOutputStream(), session.getOutputStream() ); session.setIsSecure( false ); session.setFTPBean( bean ); } else { tryingToConnect = false; } } else { // give up LString lmsg = new LString(classPath + "connectionFailed2", "[^0]: connection failed"); if ( null != hostName ) { lmsg.replace( 0, hostName ); } else { lmsg.replace( 0, "" ); } ErrorDialog.showDialog( new LString(classPath + "connectionFailed.dialogTitle", "Connection Failed"), lmsg ); tryingToConnect = false; } return tryAgain; } private void setClientCert( SSLFTP ftp ) { File privateFile = Client.getClientPrivateKey(); File publicFile = Client.getClientPublicCert(); File caFile = Client.getClientCACert(); String password = Client.getClientCertPassword(); File[] certs = null; if ( privateFile != null && publicFile != null ) { if ( null == caFile ) { certs = new File[1]; certs[0] = publicFile; } else { certs = new File[2]; certs[0] = publicFile; certs[1] = caFile; } try { ftp.setClientAuthentication( privateFile, certs, password ); } catch ( Exception e ) { try { ftp.clearClientAuthentication(); } catch ( Exception e1 ) {} } } else { try { ftp.clearClientAuthentication(); } catch ( Exception e1 ) {} } } }