Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: mindbright/ssh/SSHCommandShellImpl.java


1   /******************************************************************************
2    *
3    * Copyright (c) 1998,99 by Mindbright Technology AB, Stockholm, Sweden.
4    *                 www.mindbright.se, info@mindbright.se
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: nallen $
18   * $Date: 2001/11/12 16:31:18 $
19   * $Name:  $
20   *****************************************************************************/
21  package mindbright.ssh;
22  
23  import java.io.*;
24  import java.awt.*;
25  
26  import mindbright.terminal.*;
27  import mindbright.security.*;
28  
29  public final class SSHCommandShellImpl implements SSHCommandShell {
30  
31    static Toolkit toolkit = Toolkit.getDefaultToolkit();
32  
33    SSHStdIO stdio;
34  
35    int      escapeIdx;
36    String   escapeString = "~$";
37  
38    public void setStdIO(SSHStdIO stdio) {
39      this.stdio = stdio;
40    }
41  
42    // One hell of a kludge all this... (a bit better now at least...)
43    //
44    public String getNextArg(String args) {
45      int i = args.indexOf(' ');
46      if(i > -1)
47        args = args.substring(0, i);
48      return args;
49    }
50    public String[] makeArgv(String cmdLine) {
51      String[] argv = new String[32];
52      String[] argvRet;
53      int n = 0, i;
54      while(cmdLine != null) {
55        argv[n++] = getNextArg(cmdLine);
56        i = cmdLine.indexOf(' ');
57        if(i > -1) {
58    cmdLine = cmdLine.substring(i);
59    cmdLine = cmdLine.trim();
60        } else
61    cmdLine = null;
62      }
63      argvRet = new String[n];
64      System.arraycopy(argv, 0, argvRet, 0, n);
65      return argvRet;
66    }
67    public void doHelp() {
68      stdio.println("The following commands are available:");
69      stdio.println("");
70      stdio.println("go                                    Start SSH-session with current settings.");
71      stdio.println("quit                                  Quit program (or disconnect if connected).");
72      stdio.println("add <l|r> [/<plug>/]<port>:<host>:<port>  (see below).");
73      stdio.println("del l <local-host>:<listen-port>|*    Delete local forward (* = all).");
74      stdio.println("del r <listen-port>|*                 Delete remote forward (* = all).");
75      stdio.println("list [ssh | term]                     Lists ssh- and/or terminal-settings.");
76      stdio.println("set [<parameter> <value>]             Set value of a ssh-parameter.");
77      stdio.println("tset [<parameter> <value>]            Set value of a terminal-parameter.");
78      stdio.println("key [<bits>]                          Generate RSA key-pair (of length <bits>).");
79      stdio.println("help                                  Display this list, but you knew that :-).");
80      stdio.println("");
81      stdio.println("(do 'set' without arguments to list parameter-usage)");
82      stdio.println("");
83      stdio.println("Examples of adding a remote/local tunnel:");
84      stdio.println("> add r 4711:www.foo.com:80           Adds a remote tunnel at port 4711 back to");
85      stdio.println("                                      www.foo.com port 80 without a plugin,");
86      stdio.println("                                      i.e. default tunneling behaviour.");
87      stdio.println("> add l /ftp/4711:ftp.bar.com:21      Adds a local tunnel going to ftp.bar.com");
88      stdio.println("                                      port 21 using the ftp protocol-plugin to");
89      stdio.println("                                      handle protocol specific needs.");
90      stdio.println("");
91      stdio.println("NOTE: The first character of the command can be used instead of the full word.");
92      stdio.println("");
93    }
94    public void doHelpSet() {
95      int i;
96      stdio.println("SSH-parameters:");
97      stdio.println("");
98      for(i = 0; i < stdio.client.propsHandler.defaultPropDesc.length; i++) {
99        stdio.println(stdio.client.propsHandler.defaultPropDesc[i][stdio.client.propsHandler.PROP_NAME] + "\t: " +
100         stdio.client.propsHandler.defaultPropDesc[i][stdio.client.propsHandler.PROP_DESC]);
101     }
102     stdio.println("(to see possible parameter-values use 'list')");
103   }
104   public void doHelpTSet() {
105     int i;
106     stdio.println("Terminal-parameters:");
107     stdio.println("");
108     for(i = 0; i < TerminalDefProps.defaultPropDesc.length; i++) {
109       stdio.println(TerminalDefProps.defaultPropDesc[i][TerminalDefProps.PROP_NAME] + "\t: " +
110         TerminalDefProps.defaultPropDesc[i][TerminalDefProps.PROP_DESC]);
111     }
112     stdio.println("(to see possible parameter-values use 'list')");
113   }
114   public void doAdd(String[] argv) {
115     if(argv.length < 3 || (!argv[1].equals("l") && !argv[1].equals("r")))
116       doHelp();
117     else {
118       try {
119   if(argv[1].equals("l"))
120     stdio.client.propsHandler.setProperty("local" + stdio.client.localForwards.size(), argv[2]);
121   else
122     stdio.client.propsHandler.setProperty("remote" + stdio.client.remoteForwards.size(), argv[2]);
123       } catch (Exception e) {
124   doHelp();
125       }
126     }
127   }
128   public void doDel(String[] argv) {
129     if(argv.length < 3 || (!argv[1].equals("l") && !argv[1].equals("r")))
130       doHelp();
131     else {
132       try {
133   int port;
134   if(argv[2].equals("*"))
135     port = -1;
136   if(argv[1].equals("l")) {
137     int d = argv[2].indexOf(':');
138     String host;
139     host = argv[2].substring(0, d);
140     port = Integer.parseInt(argv[2].substring(d + 1));
141     stdio.client.delLocalPortForward(host, port);
142   } else {
143     port = Integer.parseInt(argv[2]);
144     stdio.client.delRemotePortForward(port);
145   }
146       } catch (Exception e) {
147   doHelp();
148       }
149     }
150   }
151   public void doListSSH() {
152     int i;
153     stdio.println("");
154     if(stdio.term != null)
155       stdio.term.setAttribute(Terminal.ATTR_BOLD, true);
156     stdio.println("SSH settings:");
157     if(stdio.term != null)
158       stdio.term.setAttribute(Terminal.ATTR_BOLD, false);
159 
160     for(i = 0; i < stdio.client.propsHandler.defaultPropDesc.length; i++) {
161       String propName = stdio.client.propsHandler.defaultPropDesc[i][stdio.client.propsHandler.PROP_NAME];
162       String propVal  = stdio.client.propsHandler.getProperty(propName);
163       stdio.println(propName + "\t: " + (propVal.equals("") ? "<not set>" : propVal) + " " +
164         stdio.client.propsHandler.defaultPropDesc[i][stdio.client.propsHandler.PROP_ALLOWED]);
165     }
166 
167     stdio.println("");
168     stdio.println("local tunnels:");
169     for(i = 0; i < stdio.client.localForwards.size(); i++) {
170       SSHClient.LocalForward fwd = (SSHClient.LocalForward) stdio.client.localForwards.elementAt(i);
171       stdio.println("\tlocal:  " + fwd.localPort + "\tremote: " + fwd.remoteHost + "/" +
172         fwd.remotePort + " (plugin: " + fwd.plugin + ")");
173     }
174     if(i == 0)
175       stdio.println("\t<none>");
176     stdio.println("remote tunnels:");
177     for(i = 0; i < stdio.client.remoteForwards.size(); i++) {
178       SSHClient.RemoteForward fwd = (SSHClient.RemoteForward) stdio.client.remoteForwards.elementAt(i);
179       stdio.println("\tremote: " + fwd.remotePort + "\tlocal:  " + fwd.localHost + "/" +
180         fwd.localPort + " (plugin: " + fwd.plugin + ")");
181     }
182     if(i == 0)
183       stdio.println("\t<none>");
184     stdio.println("");
185 
186     if(stdio.client.isOpened()) {
187       if(stdio.term != null)
188   stdio.term.setAttribute(Terminal.ATTR_BOLD, true);
189       stdio.println("Currently active tunnels:");
190       if(stdio.term != null)
191   stdio.term.setAttribute(Terminal.ATTR_BOLD, false);
192       String[] list = stdio.controller.listTunnels();
193       if(list.length == 0)
194   stdio.print("\t<none>");
195       else {
196   for(i = 0; i < list.length; i++)
197     stdio.println("\t" + list[i]);
198       }
199       stdio.println("");
200     }
201   }
202 
203   public void doListTerm() {
204     int i;
205     stdio.println("");
206 
207     if(stdio.term != null) {
208       TerminalWin termwin = (TerminalWin)stdio.term;
209       stdio.term.setAttribute(Terminal.ATTR_BOLD, true);
210       stdio.println("Terminal settings:");
211       stdio.term.setAttribute(Terminal.ATTR_BOLD, false);
212 
213       for(i = 0; i < TerminalDefProps.defaultPropDesc.length; i++) {
214   String propName = TerminalDefProps.defaultPropDesc[i][TerminalDefProps.PROP_NAME];
215   stdio.println(propName + "\t: " + termwin.getProperty(propName) + " " +
216     TerminalDefProps.defaultPropDesc[i][TerminalDefProps.PROP_ALLOWED]);
217       }
218 
219       stdio.println("");
220     }
221   }
222 
223   public void doSet(String[] argv) {
224     if(argv.length < 3) {
225       doHelpSet();
226     } else {
227       try {
228   String prm = argv[1];
229   String arg = argv[2];
230   stdio.client.propsHandler.setProperty(prm, arg);
231       } catch (Exception e) {
232   stdio.println(e.getMessage());
233   stdio.println("(use 'set' without parameters to get help on available parameters)");
234       }
235     }
236   }
237   public void doTSet(String[] argv) {
238     if(argv.length < 3) {
239       doHelpTSet();
240     } else {
241       String prm = argv[1];
242       String arg = argv[2];
243       TerminalWin termwin = null;
244       if(stdio.term instanceof TerminalWin)
245   termwin = (TerminalWin)stdio.term;
246       if(termwin != null) {
247   try {
248     termwin.setProperty(prm, arg);
249   } catch (Exception e) {
250     stdio.println(e.getMessage());
251     stdio.println("(use 'tset' without parameters to get help on available parameters)");
252   }
253       } else {
254   stdio.println("Can't set terminal-parameters in dumb-console mode.");
255       }
256     }
257   }
258   public void doGenKey(String[] argv) {
259     String fileName, passwd, comment;
260     KeyPair kp;
261     int     bits = 1024;
262 
263     stdio.println("");
264 
265     if(argv.length > 1) {
266       try {
267   bits = Integer.parseInt(argv[1]);
268       } catch(Exception e) {
269   stdio.println("(invalid <bits>, using default 1024)");
270       }
271     }
272 
273     try {
274       stdio.println("The key-pair will be stored in a file with the name you enter.");
275       stdio.println("Files are stored in '" + stdio.client.propsHandler.getSSHHomeDir() + "' if no path is given.");
276       stdio.println("(note: the public key will also be stored in a file with ext. '.pub')");
277       fileName = stdio.promptLine("Filename to save identity in: " , "", false);
278       if(!fileName.startsWith(File.separator))
279   fileName = stdio.client.propsHandler.getSSHHomeDir() + fileName;
280       do {
281       passwd   = stdio.promptLine("Password to protect private key: " , "", true);
282       } while(!passwd.equals(stdio.promptLine("Password again: " , "", true)));
283       comment  = stdio.promptLine("Comment to store in key-files: " , "", false);
284       stdio.print("Generating identity of length " + bits + "...");
285       try {
286   Thread.sleep(100); // !!! let the text show... (?)
287       } catch (InterruptedException e) {
288   // !!!
289       }
290       kp = SSH.generateRSAKeyPair(bits, SSH.secureRandom());
291       stdio.println("done");
292       String pks = SSH.generateKeyFiles(kp, fileName, passwd, comment);
293       stdio.setSelection(pks);
294       stdio.selectionAvailable(true);
295     } catch (Exception ee) {
296       stdio.println("An error occured while generating key...");
297     }
298       stdio.println("");
299   }
300 
301   public boolean doCommandShell() {
302     boolean retVal = true;
303     stdio.println("");
304     stdio.println("...entering local command-shell (type 'h' for help).");
305     stdio.println("");
306     try {
307       boolean keepRunning = true;
308       String[] argv;
309       while(keepRunning) {
310   String cmdLine = stdio.promptLine("mindterm> ", null, false);
311   String cmd;
312   cmdLine = cmdLine.toLowerCase();
313   cmdLine = cmdLine.trim();
314   if(cmdLine.equals(""))
315     continue;
316   argv = makeArgv(cmdLine);
317   cmd  = argv[0];
318   if(cmd.equals("l") || cmd.equals("list")) {
319     if(argv.length > 1) {
320       if(argv[1].equals("ssh") || argv[1].equals("term")) {
321         if(argv[1].equals("ssh"))
322     doListSSH();
323         else
324     doListTerm();
325         stdio.println("(permitted values are in parentheses on the right)");
326         stdio.println("");
327       } else
328         stdio.println("usage: 'list [ssh | term]'");
329     } else {
330       doListSSH();
331       doListTerm();
332       stdio.println("(permitted values are in parentheses on the right)");
333       stdio.println("");
334     }
335   } else if(cmd.equals("a") || cmd.equals("add")) {
336   doAdd(argv);
337   } else if(cmd.equals("d") || cmd.equals("del")) {
338     doDel(argv);
339   } else if(cmd.equals("s") || cmd.equals("set")) {
340     doSet(argv);
341   } else if(cmd.equals("t") || cmd.equals("ts") || cmd.equals("tset")) {
342     doTSet(argv);
343   } else if(cmd.equals("help") || cmd.equals("?") || cmd.equals("h")) {
344     doHelp();
345   } else if(cmd.equals("go") || cmd.equals("g")) {
346     retVal      = true;
347     keepRunning = false;
348   } else if(cmd.equals("key")) {
349     doGenKey(argv);
350   } else if(cmd.equals("q") || cmd.equals("quit")) {
351     retVal      = false;
352     keepRunning = false;
353   } else {
354     doHelp();
355   }
356       }
357     } catch (SSHStdIO.CtrlDPressedException e) {
358       retVal = true;
359     } catch (Exception e) {
360       retVal = false;
361     }
362     return retVal;
363   }
364 
365   public void launchCommandShell() {
366     (new Thread(new Runnable() {
367       public void run() { 
368         stdio.isConnected = false;
369   if(!doCommandShell()) {
370     stdio.controller.sendDisconnect("exit");
371   } else {
372     stdio.isConnected = true;
373     try {
374       stdio.typedChar((char)0x0c);
375     } catch (IOException e) {
376       // !!!
377     }
378   }
379       }
380     })).start();
381   }
382 
383   public boolean escapeSequenceTyped(char c) {
384     if(c == escapeString.charAt(escapeIdx))
385       escapeIdx++;
386     else
387       escapeIdx = 0;
388     if(escapeIdx == escapeString.length()) {
389       escapeIdx = 0;
390       return true;
391     }
392     return false;
393   }
394 
395   public String escapeString() {
396       return escapeString;
397   }
398 
399 }