source: other-projects/trunk/gs3-release-maker/tasks/sshtaskdef/src/mindbright/ssh/SSHInteractiveClient.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 13.0 KB
Line 
1/******************************************************************************
2 *
3 * Copyright (c) 1998,99 by Mindbright Technology AB, Stockholm, Sweden.
4 * www.mindbright.se, [email protected]
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 *****************************************************************************
17 * $Author: mats $
18 * $Date: 2000/08/02 19:08:43 $
19 * $Name: rel1-2-1 $
20 *****************************************************************************/
21package mindbright.ssh;
22
23import java.util.Properties;
24import java.io.IOException;
25import java.io.FileNotFoundException;
26import java.net.UnknownHostException;
27
28import mindbright.terminal.*;
29import mindbright.security.*;
30
31import mindbright.net.*;
32
33public final class SSHInteractiveClient extends SSHClient
34 implements Runnable, SSHInteractor {
35
36 public static final boolean expires = false;
37 public static final boolean licensed = false;
38
39 public static final String licenseMessage = "This copy of MindTerm is licensed to ";
40 public static final String licensee = "nobody";
41
42 public static final long validFrom = 965157940452L; // 000801/21:25
43 public static final long validTime = (33L * 24L * 60L * 60L * 1000L);
44
45 public static boolean wantHelpInfo = true;
46 public static String customStartMessage = null;
47
48 Thread dumbConsoleThread;
49
50 SSHMenuHandler menus;
51 SSHStdIO sshStdIO;
52 SSHPropertyHandler propsHandler;
53
54 public boolean quiet;
55 boolean initQuiet;
56
57 static public class DumbConsoleThread implements Runnable {
58 SSHChannelController controller;
59 SSHStdIO console;
60
61 public DumbConsoleThread(SSHChannelController controller, SSHStdIO console) {
62 this.controller = controller;
63 this.console = console;
64 }
65
66 public void run() {
67 SSHPduOutputStream stdinPdu;
68 String line;
69 try {
70 while(true) {
71 line = console.promptLine("", "", false);
72 stdinPdu = new SSHPduOutputStream(SSH.CMSG_STDIN_DATA, console.sndCipher);
73 stdinPdu.writeString(line + "\n");
74 controller.transmit(stdinPdu);
75 Thread.sleep(400);
76 }
77 } catch (SSHStdIO.CtrlDPressedException e) {
78 controller.sendDisconnect("exit");
79 } catch (Exception e) {
80 controller.alert("Error in console-thread: " + e.toString());
81 }
82 }
83 }
84
85 public static String copyright() {
86 return "Copyright (c) 1998-2000 by Mindbright Technology AB, Stockholm, Sweden";
87 }
88
89 public SSHInteractiveClient(boolean quiet, boolean cmdsh, SSHPropertyHandler propsHandler) {
90 super(propsHandler, propsHandler);
91
92 this.propsHandler = propsHandler;
93 this.interactor = this; // !!! OUCH
94
95 propsHandler.setInteractor(this);
96 propsHandler.setClient(this);
97
98 this.quiet = quiet;
99 this.initQuiet = quiet;
100
101 setConsole(new SSHStdIO());
102 sshStdIO = (SSHStdIO)console;
103 sshStdIO.setClient(this);
104 sshStdIO.enableCommandShell(cmdsh);
105 }
106
107 public SSHInteractiveClient(SSHInteractiveClient clone) {
108 this(true, clone.sshStdIO.hasCommandShell(), new SSHPropertyHandler(clone.propsHandler));
109
110 this.activateTunnels = false;
111
112 this.wantHelpInfo = clone.wantHelpInfo;
113 this.customStartMessage = clone.customStartMessage;
114 }
115
116 public void setMenus(SSHMenuHandler menus) {
117 this.menus = menus;
118 }
119
120 public SSHPropertyHandler getPropertyHandler() {
121 return propsHandler;
122 }
123
124 public void updateMenus() {
125 if(menus != null)
126 menus.update();
127 }
128
129 public void printCopyright() {
130 console.println(copyright());
131
132 if(licensed) {
133 console.println(licenseMessage + licensee);
134 }
135
136 if(customStartMessage != null) {
137 console.println(customStartMessage);
138 }
139 }
140
141 void printHelpInfo() {
142 if(!wantHelpInfo)
143 return;
144
145 if(propsHandler.getSSHHomeDir() != null)
146 console.println("MindTerm home: " + propsHandler.getSSHHomeDir());
147
148 if(sshStdIO.hasCommandShell()) {
149 console.println("\tpress <ctrl> + 'D' to enter local command shell");
150 if(isDumb())
151 console.println("\t(...you might have to press ENTER also...)");
152 }
153 if(menus != null && menus.havePopupMenu) {
154 console.println("\tpress <ctrl> + <mouse-" + menus.getPopupButton() + "> for main-menu");
155 }
156 console.println("");
157 }
158
159 boolean hasExpired() {
160 boolean expired = false;
161 long now = System.currentTimeMillis();
162
163 if(licensed)
164 return false;
165
166 if(expires) {
167 int daysRemaining = (int)((validTime - (now - validFrom)) / (1000L * 60L * 60L * 24L));
168 if(daysRemaining <= 0) {
169 console.println("This is a demo version of MindTerm, it has expired!");
170 console.println("Please go to http://www.mindbright.se/mindterm/ to get a copy");
171 expired = true;
172 } else {
173 console.println("");
174 console.println("This is a demo version of MindTerm, it will expire in " + daysRemaining + " days");
175 console.println("");
176 }
177 } else {
178 int daysOld = (int)((now - validFrom) / (1000L * 60L * 60L * 24L));
179 console.println("");
180 console.println("This is a demo version of MindTerm, it is " + daysOld + " days old.");
181 console.println("Please go to http://www.mindbright.se/mindterm/");
182 console.println("\tto check for new versions now and then");
183 console.println("");
184 }
185 return expired;
186 }
187
188 void initRandomSeed() {
189 console.print("Initializing random generator, please wait...");
190 SSH.initSeedGenerator();
191 console.println("done");
192 }
193
194 public void doSingleCommand(String commandLine, boolean background, long msTimeout)
195 throws IOException {
196 boolean haveDumbConsole = (propsHandler.wantPTY() && isDumb());
197
198 initRandomSeed();
199 console.println("");
200
201 printHelpInfo();
202
203 this.commandLine = commandLine;
204
205 if(NETSCAPE_SECURITY_MODEL) {
206 try {
207 netscape.security.PrivilegeManager.enablePrivilege("TerminalEmulator");
208 console.println("Full network access granted, can do tunneling and connect to any host");
209 } catch (netscape.security.ForbiddenTargetException e) {
210 console.println("Full network access denied, normal applet security applies");
211 }
212 console.println("");
213 }
214
215 bootSSH(false);
216
217 if(haveDumbConsole) {
218 startDumbConsole();
219 }
220
221 if(background)
222 startExitMonitor(msTimeout);
223 else
224 waitForExit(msTimeout);
225
226 if(haveDumbConsole) {
227 stopDumbConsole();
228 }
229 }
230
231 public void run() {
232 boolean doCommandShell;
233 boolean gotExtMsg;
234
235 initRandomSeed();
236
237 if(NETSCAPE_SECURITY_MODEL) {
238 try {
239 netscape.security.PrivilegeManager.enablePrivilege("TerminalEmulator");
240 console.println("Full network access granted, can do tunneling and connect to any host");
241 } catch (netscape.security.ForbiddenTargetException e) {
242 console.println("Full network access denied, normal applet security applies");
243 }
244 console.println("");
245 }
246
247 if(hasExpired()) {
248 while(true) {
249 try {
250 Thread.sleep(100000);
251 } catch (InterruptedException e) {
252 }
253 }
254 }
255
256 boolean keepRunning = true;
257 while(keepRunning) {
258 doCommandShell = false;
259 gotExtMsg = false;
260 try {
261 console.println("");
262 printHelpInfo();
263
264 // This starts a connection to the sshd and all the related stuff...
265 //
266 bootSSH(true);
267
268 if(isDumb())
269 startDumbConsole();
270
271 // Join main receiver channel thread and wait for session to end
272 //
273 controller.waitForExit();
274
275 if(isDumb())
276 stopDumbConsole();
277
278 if(sshStdIO.isConnected()) {
279 // Server died on us without sending disconnect
280 sshStdIO.serverDisconnect("\n\r\n\rServer died or connection lost");
281 }
282
283 // !!! Wait for last session to close down entirely (i.e. so
284 // disconnected gets a chance to be called...)
285 //
286 Thread.sleep(1000);
287
288 try {
289 propsHandler.checkSave();
290 } catch (IOException e) {
291 alert("Error saving settings!");
292 }
293
294 } catch(SSHClient.AuthFailException e) {
295 console.println("");
296 console.println(e.getMessage());
297 propsHandler.clearPasswords();
298
299 } catch(WebProxyException e) {
300 console.println("");
301 console.println(e.getMessage());
302 propsHandler.clearPasswords();
303
304 } catch(SSHStdIO.CtrlDPressedException e) {
305 doCommandShell = true;
306
307 } catch(SSHStdIO.SSHExternalMessage e) {
308 gotExtMsg = true;
309 console.println("");
310 console.println(e.getMessage());
311
312 } catch(UnknownHostException e) {
313 String host = e.getMessage();
314 if(propsHandler.getProperty("proxytype").equals("none")) {
315 console.println("Unknown host: " + host);
316 } else {
317 console.println("Unknown proxy host: " + host);
318 }
319 propsHandler.clearServerSetting();
320
321 } catch(FileNotFoundException e) {
322 console.println("File not found: " + e.getMessage());
323
324 } catch(Exception e) {
325 String msg = e.getMessage();
326 if(msg == null || msg.trim().length() == 0)
327 msg = e.toString();
328 console.println("");
329 console.println("Error connecting to " + propsHandler.getProperty("server") + ", reason:");
330 console.println("-> " + msg);
331 if(SSH.DEBUGMORE) {
332 System.out.println("If an error occured, please send the below stacktrace to [email protected]");
333 e.printStackTrace();
334 }
335
336 } catch(ThreadDeath death) {
337 if(controller != null)
338 controller.killAll();
339 controller = null;
340 throw death;
341 }
342
343 propsHandler.passivateProperties();
344 activateTunnels = true;
345 propsHandler.currentPropsFile = null;
346
347 if(!propsHandler.savePasswords || usedOTP) {
348 propsHandler.clearPasswords();
349 }
350
351 if(!gotExtMsg) {
352 if(!propsHandler.autoLoadProps) {
353 propsHandler.clearPasswords();
354 initQuiet = false;
355 }
356 quiet = false;
357 }
358
359 controller = null;
360
361 TerminalWin t = getTerminalWin();
362 if(t != null)
363 t.setTitle(null);
364
365 if(doCommandShell && sshStdIO.hasCommandShell()) {
366 keepRunning = sshStdIO.commandShell.doCommandShell();
367 }
368 }
369 }
370
371 public boolean isDumb() {
372 return (console.getTerminal() == null);
373 }
374
375 public TerminalWin getTerminalWin() {
376 Terminal term = console.getTerminal();
377 if(term != null && term instanceof TerminalWin)
378 return (TerminalWin)term;
379 return null;
380 }
381
382 public void startDumbConsole() {
383 Runnable dumbConsole = new DumbConsoleThread(controller, sshStdIO);
384 dumbConsoleThread = new Thread(dumbConsole);
385 dumbConsoleThread.start();
386 }
387 public void stopDumbConsole() {
388 dumbConsoleThread.stop();
389 }
390
391 public void updateTitle() {
392 sshStdIO.updateTitle();
393 }
394
395 //
396 // SSHInteractor interface
397 //
398 public void propsStateChanged(SSHPropertyHandler props) {
399 updateMenus();
400 }
401
402 public void startNewSession(SSHClient client) {
403 // !!! REMOVE
404 // Here we can have a login-dialog with proxy-info also (or configurable more than one method)
405 // !!!
406 }
407
408 public void sessionStarted(SSHClient client) {
409 quiet = initQuiet;
410 }
411
412 public boolean quietPrompts() {
413 return (commandLine != null || quiet);
414 }
415
416 public boolean isVerbose() {
417 return wantHelpInfo;
418 }
419
420 public String promptLine(String prompt, String defaultVal) throws IOException {
421 return sshStdIO.promptLine(prompt, defaultVal, false);
422 }
423
424 public String promptPassword(String prompt) throws IOException {
425 return sshStdIO.promptLine(prompt, "", true);
426 }
427
428 public boolean askConfirmation(String message, boolean defAnswer) {
429 boolean confirm = false;
430 try {
431 confirm = askConfirmation(message, true, defAnswer);
432 } catch (IOException e) {
433 // !!!
434 }
435 return confirm;
436 }
437
438 public boolean askConfirmation(String message, boolean preferDialog, boolean defAnswer) throws IOException {
439 boolean confirm = false;
440 if(menus != null && preferDialog) {
441 confirm = menus.confirmDialog(message, defAnswer);
442 } else {
443 String answer = promptLine(message + (defAnswer ? " ([yes]/no) " : "(yes/[no]) "), "");
444 if(answer.equalsIgnoreCase("yes") || answer.equals("y")) {
445 confirm = true;
446 } else if(answer.equals("")) {
447 confirm = defAnswer;
448 }
449 }
450 return confirm;
451 }
452
453 public void connected(SSHClient client) {
454 updateMenus();
455 if(wantHelpInfo) {
456 console.println("Connected to server running " + srvVersionStr);
457 if(sshStdIO.hasCommandShell())
458 console.println("(command shell escape-sequence is '" + sshStdIO.commandShell.escapeString() + "')");
459 console.println("");
460 }
461 }
462
463 public void open(SSHClient client) {
464 updateMenus();
465 updateTitle();
466 }
467
468 public void disconnected(SSHClient client, boolean graceful) {
469 sshStdIO.breakPromptLine("Login aborted by user");
470 updateMenus();
471 updateTitle();
472 }
473
474 public void report(String msg) {
475 console.println(msg);
476 console.println("");
477 }
478
479 public void alert(String msg) {
480 if(menus != null) {
481 if(msg.length() < 35)
482 menus.alertDialog(msg);
483 else
484 menus.textDialog("MindTerm - Alert", msg, 4, 38, true);
485 } else {
486 report(msg);
487 }
488 }
489
490}
Note: See TracBrowser for help on using the repository browser.