2 * ch.cyberduck.ui.cocoa.CDConnectionController.java
5 * Copyright (c) 2002 David Kocher. All rights reserved.
6 * http://icu.unizh.ch/~dkocher/
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * Bug fixes, suggestions and comments should be sent to:
19 * dkocher@cyberduck.ch
22 package ch
.cyberduck
.ui
.cocoa
;
24 import com
.apple
.cocoa
.foundation
.*;
25 import com
.apple
.cocoa
.application
.*;
27 import java
.io
.IOException
;
29 import ch
.cyberduck
.core
.*;
30 import ch
.cyberduck
.core
.http
.*;
31 import ch
.cyberduck
.core
.sftp
.*;
32 import ch
.cyberduck
.core
.ftp
.*;
34 import com
.sshtools
.j2ssh
.session
.SessionChannelClient
;
35 import com
.sshtools
.j2ssh
.transport
.InvalidHostFileException
;
36 import com
.sshtools
.j2ssh
.transport
.HostKeyVerification
;
37 import com
.sshtools
.j2ssh
.authentication
.PasswordAuthentication
;
38 import com
.sshtools
.j2ssh
.authentication
.AuthenticationProtocolState
;
39 import com
.sshtools
.j2ssh
.sftp
.*;
40 import com
.sshtools
.j2ssh
.*;
42 import org
.apache
.log4j
.Appender
;
43 import org
.apache
.log4j
.Logger
;
45 public class CDConnectionController
extends NSObject
{
47 private static Logger log
= Logger
.getLogger(CDConnectionController
.class);
49 public NSWindow mainWindow
; /* IBOutlet */
50 public NSWindow connectionSheet
; /* IBOutlet */
51 public NSWindow loginSheet
; /* IBOutlet */
53 public NSSecureTextField passwordField
; /* IBOutlet */
54 public NSTextField pathField
; /* IBOutlet */
55 public NSTextField portField
; /* IBOutlet */
56 public NSPopUpButton protocolPopup
; /* IBOutlet */
57 public NSTextField hostField
; /* IBOutlet */
58 public NSTextField usernameField
; /* IBOutlet */
59 public NSTextView logTextView
; /* IBOutlet */
60 public NSProgressIndicator progressIndicator
; /* IBOutlet */
62 public NSTextField statusLabel
; /* IBOutlet */
63 public NSTableView browserTable
; /* IBOutlet */
64 public NSView connectedListView
; /* IBOutlet */
66 private CDConnectionController controller
= this;
68 public CDConnectionController() {
70 log
.debug("CDConnectionController");
73 public void awakeFromNib() {
74 // log.addAppender(statusLabel);
78 public void connect(NSObject sender
) {
82 String protocol
= null;
83 int tag
= protocolPopup
.selectedItem().tag();
86 protocol
= Session
.SFTP
;
89 protocol
= Session
.FTP
;
92 // protocol = Session.HTTP;
96 //@todo new connection via menu item recent connection
97 // if(sender instanceof NSMenu
98 //NSMenuItem item = menu.getSelectedItem()
101 if(sender
instanceof NSTextField
) {
102 host
= new Host(protocol
, ((NSControl
)sender
).stringValue(), 22, null, null);
104 if(sender
instanceof NSButton
) {
105 NSApplication
.sharedApplication().endSheet(connectionSheet
, NSAlertPanel
.AlternateReturn
);
106 host
= new Host(protocol
, hostField
.stringValue(), 22, usernameField
.stringValue(), passwordField
.stringValue());
109 mainWindow
.setTitle(host
.getName());
110 Session session
= host
.getSession(new TransferAction(TransferAction
.LIST
));
112 // log.debug(session.toString());
114 catch(IOException e
) {
115 log
.error(e
.toString());
117 // connectedListView.addSubview(new CDConnectedItemView(host));
118 // connectedListView.setNeedsDisplay(true);
120 // Thread session = new Session(host);
123 // // Now try to write to a file without creating it!
124 //SftpFile file = sftp.openFile("shinning.txt",
125 // SftpSubsystemClient.OPEN_CREATE
126 // | SftpSubsystemClient.OPEN_WRITE);
131 public void disconnect(NSObject sender
) {
132 log
.debug("disconnect");
137 private class Session extends Thread {
140 public Session(Host host) {
145 SshClient SSH = new SshClient();
146 SSH.connect(hostField.stringValue(), new CDHostKeyVerification());
147 PasswordAuthentication auth = new PasswordAuthentication();
148 auth.setUsername(usernameField.stringValue());
149 auth.setPassword(passwordField.stringValue());
150 int result = SSH.authenticate(auth);
151 if (result == AuthenticationProtocolState.COMPLETE) {
152 SessionChannelClient session = SSH.openSessionChannel();
153 SftpSubsystemClient SFTP = new SftpSubsystemClient();
154 session.startSubsystem(SFTP);
155 SftpFile workingDirectory = SFTP.openDirectory(".");
156 java.util.List children = new java.util.ArrayList();
157 CDBrowserTableDataSource browserTableDataSource = (CDBrowserTableDataSource)browserTable.dataSource();
160 read = SFTP.listChildren(workingDirectory, children);
162 java.util.Iterator i = children.iterator();
163 browserTableDataSource.clear();
165 browserTableDataSource.addEntry(i.next());
166 browserTable.reloadData();
171 NSApplication.sharedApplication().beginSheet(loginSheet, mainWindow, null,
174 new Class[] { NSWindow.class, int.class, NSWindow.class }
177 log.info("Authentication failed.");
180 catch(InvalidHostFileException e) {
183 catch(java.io.IOException e) {
188 public void loginSheetDidEnd(NSWindow sheet, int returncode, NSWindow main) {
195 public void closeLoginSheet(NSObject sender
) {
196 // Ends a document modal session by specifying the sheet window, sheet. Also passes along a returnCode to the delegate.
197 NSApplication
.sharedApplication().endSheet(loginSheet
, NSAlertPanel
.AlternateReturn
);
200 private class CDHostKeyVerification
extends HostKeyVerification
{
202 private String fingerprint
;
204 private boolean done
;
206 public boolean isDone() {
210 public CDHostKeyVerification() throws InvalidHostFileException
{
212 log
.debug("CDHostKeyVerification");
215 public CDHostKeyVerification(String hostFile
) throws InvalidHostFileException
{
219 public void onDeniedHost(String hostname
) {
220 log
.debug("onDeniedHost");
221 NSAlertPanel
.beginInformationalAlertSheet(
222 "Access denied", //title
223 "OK",// defaultbutton
224 null,//alternative button
230 "deniedHostSheetDidEnd",
233 NSWindow
.class, int.class, NSWindow
.class
236 null, // dismiss selector
238 "Access to the host " + hostname
+ " is denied from this system" // message
240 while(!this.isDone()) {
242 Thread
.sleep(500); //milliseconds
244 catch(InterruptedException e
) {
250 public void onHostKeyMismatch(String host
, String fingerprint
, String actualHostKey
) {
251 log
.debug("onHostKeyMismatch");
253 this.fingerprint
= fingerprint
;
254 NSAlertPanel
.beginInformationalAlertSheet(
255 "Host key mismatch", //title
256 "Allow",// defaultbutton
257 "Deny",//alternative button
258 isHostFileWriteable() ?
"Always" : null,//other button
263 "keyMismatchSheetDidEnd",
266 NSWindow
.class, int.class, NSWindow
.class
269 null, // dismiss selector
271 "The host key supplied by " + host
+ " is: "
273 "The current allowed key for " + host
+ " is: "
274 + fingerprint
+"\nDo you want to allow the host access?");
275 while(!this.isDone()) {
277 Thread
.sleep(500); //milliseconds
279 catch(InterruptedException e
) {
286 public void onUnknownHost(String host
, String fingerprint
) {
287 log
.debug("onUnknownHost");
289 this.fingerprint
= fingerprint
;
290 NSAlertPanel
.beginInformationalAlertSheet(
291 "Unknown host", //title
292 "Allow",// defaultbutton
293 "Deny",//alternative button
294 isHostFileWriteable() ?
"Always" : null,//other button
299 "unknownHostSheetDidEnd",
302 NSWindow
.class, int.class, NSWindow
.class
305 null, // dismiss selector
308 + " is currently unknown to the system. The host key fingerprint is: " + fingerprint
+".");
309 while(!this.isDone()) {
311 Thread
.sleep(500); //milliseconds
313 catch(InterruptedException e
) {
320 public void deniedHostSheetDidEnd(NSWindow sheet
, int returncode
, NSWindow main
) {
321 log
.debug("deniedHostSheetDidEnd");
326 public void keyMismatchSheetDidEnd(NSWindow sheet
, int returncode
, NSWindow main
) {
327 log
.debug("keyMismatchSheetDidEnd");
329 if(returncode
== NSAlertPanel
.DefaultReturn
)
330 allowHost(host
, fingerprint
, false);
331 if(returncode
== NSAlertPanel
.AlternateReturn
) {
333 NSAlertPanel
.beginInformationalAlertSheet(
334 "Invalid host key", //title
335 "OK",// defaultbutton
336 null,//alternative button
341 null, // dismiss selector
343 "Cannot continue without a valid host key." // message
345 log
.info("Cannot continue without a valid host key");
347 if(returncode
== NSAlertPanel
.OtherReturn
)
351 catch(InvalidHostFileException e
) {
356 public void unknownHostSheetDidEnd(NSWindow sheet
, int returncode
, NSWindow main
) {
357 log
.debug("unknownHostSheetDidEnd");
359 if(returncode
== NSAlertPanel
.DefaultReturn
)
360 allowHost(host
, fingerprint
, false); // allow host
361 if(returncode
== NSAlertPanel
.AlternateReturn
) {
363 NSAlertPanel
.beginInformationalAlertSheet(
364 "Invalid host key", //title
365 "OK",// defaultbutton
366 null,//alternative button
371 null, // dismiss selector
373 "Cannot continue without a valid host key." // message
375 log
.info("Cannot continue without a valid host key");
377 if(returncode
== NSAlertPanel
.OtherReturn
)
378 allowHost(host
, fingerprint
, true); // always allow host
381 catch(InvalidHostFileException e
) {