1 /*
2  * @(#) $Id: JSTKShellClient.java,v 1.2 2003/07/08 08:13:53 pankaj Exp $
3  *
4  * Copyright (c) 2002-03 by Pankaj Kumar (http://www.pankaj-k.net). 
5  * All rights reserved.
6  *
7  * The license governing the use of this file can be found in the 
8  * root directory of the containing software.
9  */
10package org.jstk.jstksh;
11
12import java.util.HashMap;
13import java.io.FileReader;
14import java.io.File;
15import java.io.FileWriter;
16import java.io.PrintWriter;
17import java.io.BufferedReader;
18import java.io.IOException;
19import java.io.*;
20import java.rmi.Naming;
21import java.rmi.RemoteException;
22import java.rmi.ServerException;
23import org.jstk.*;
24import org.jstk.JSTKQuitException;
25import javax.security.auth.*;
26import javax.security.auth.callback.*;
27import javax.security.auth.login.*;
28import java.security.*;
29
30public class JSTKShellClient {
31    public static class JSTKShellCallbackHandler implements CallbackHandler {
32        public void handle(Callback[] cb) {
33            try {
34                for (int i = 0; i < cb.length; i++){
35                    if (cb[i] instanceof NameCallback){
36                        NameCallback nc = (NameCallback)cb[i];
37                        System.out.print(nc.getPrompt() + " ");
38                        System.out.flush();
39                        String name = new BufferedReader(new InputStreamReader(System.in)).readLine();
40                        nc.setName(name);
41                    } else if (cb[i] instanceof PasswordCallback){
42                        PasswordCallback pc = (PasswordCallback)cb[i];
43                        System.out.print(pc.getPrompt() + " ");
44                        System.out.flush();
45                        String pw = new BufferedReader(new InputStreamReader(System.in)).readLine();
46                        pc.setPassword(pw.toCharArray());
47                        pw = null;
48                    }
49                }
50            } catch (IOException ioe){
51                System.out.println("ioe = " + ioe);
52            }
53            // throw new IllegalArgumentException("Not completely implemented yet");
54        }
55    }
56
57    public static class JSTKShellClientAction implements PrivilegedAction {
58        private String prompt = "jstksh> ";
59
60        public void setPrompt(String prompt){
61            this.prompt = prompt;
62        }
63
64        public Object run(){
65            try {
66                JSTKShell shell = new JSTKShellServer();
67                runLoop(prompt, shell);
68                return null;
69            } catch (Exception e){
70                return e;
71            }
72        }
73    }
74
75    private static void runLoop(String prompt, JSTKShell shell) throws Exception {
76        String sessId = shell.createSession();
77        while (true){
78            System.out.print(prompt);
79            System.out.flush();
80            String cmdline = new BufferedReader(new InputStreamReader(System.in)).readLine();
81            // Embed the session Id in the request. Somewhat inefficeint but will do.
82            cmdline = cmdline + " -sessionid " + sessId;
83            String[] cmdargs = cmdline.split("\\s");
84            try {
85                String result = shell.execCommand(cmdargs);
86                System.out.println(result);
87            } catch (JSTKQuitException qe){
88                shell.destroySession(sessId);
89                return;             // Break out of the loop.
90            } catch (ServerException se){
91                if ((se.getCause() instanceof RemoteException) &&
92                        (((RemoteException)se.getCause()).getCause() instanceof JSTKQuitException)){
93                    shell.destroySession(sessId);
94                    return;
95                }
96                throw se;
97            }
98        }
99    }
00
01    private static HashMap defaults = new HashMap();
02    static {
03        defaults.put("proto", "local");
04    }
05
06    public String briefDescription(){
07        String briefDesc = "JSTKShell client";
08        return briefDesc;
09    }
10
11    public String optionsDescription(){
12        String optionsDesc =
13            "  -proto <proto> : Protocol to interact with server(local|rmi).[" +
14            defaults.get("proto") + "]\n" +
15            "  -login           : Login to server.\n";
16        return optionsDesc;
17    }
18    public String[] useForms(){
19        String[] useForms = {
20            "[-proto <proto>] [-login [-user <username>] [-pass <password>]]"
21        };
22        return useForms;
23    }
24    public String[] sampleUses(){
25        String[] sampleUses = {
26            "",
27            "-proto rmi",
28            "-login"
29        };
30        return sampleUses;
31    }
32
33    public static void main(String[] args) throws Exception {
34        JSTKOptions opts = new JSTKOptions();
35        opts.parse(args, 0);
36        opts.setDefaults(defaults);
37        String proto = opts.get("proto");
38        boolean login = Boolean.valueOf(opts.get("login")).booleanValue();
39
40        if (proto.equalsIgnoreCase("local")){   // JSTKShell object within the same JVM.
41            if (login){
42                LoginContext lc = new LoginContext("JSTKShell", new JSTKShellCallbackHandler());
43                lc.login();
44                JSTKShellClientAction action = new JSTKShellClientAction();
45                action.setPrompt("jstk-local-login>");
46                Subject.doAs(lc.getSubject(), action);
47            } else {
48                JSTKShell shell = new JSTKShellServer();
49                runLoop("jstksh-local>", shell);
50            }
51        } else if (proto.equalsIgnoreCase("rmi")){
52            if (login){
53                LoginContext lc = new LoginContext("JSTKShell", new JSTKShellCallbackHandler());
54                lc.login();
55                JSTKShell shell = (JSTKShell)Naming.lookup("//localhost/JSTKShellAuthRMIServer");
56                shell.setSubject(lc.getSubject());
57                runLoop("jstksh-rmi-login>", shell);
58                /*
59                JSTKShellClientAction action = new JSTKShellClientAction();
60                action.setPrompt("jstk-local-login>");
61                Subject.doAs(lc.getSubject(), action);
62                */
63            } else {
64                JSTKShell shell = (JSTKShell)Naming.lookup("//localhost/JSTKShellRMIServer");
65                runLoop("jstksh-rmi>", shell);
66            }
67        } else {
68            System.err.println("Unknown protocol: " + proto);
69        }
70    }
71}
72