1
10package org.jstk.jstksh;
11
12import java.util.*;
13import java.util.logging.Logger;
14import java.security.*;
15import java.io.*;
16import javax.security.auth.Subject;
17
18import org.jstk.*;
19
20
21public class JSTKShellServer extends JSTKAbstractTool implements JSTKShell {
22 private String homeDir = null;
23 private String curDir = null;
24 private static int curId = -1;
25 private static HashMap sessionTable = new HashMap();
26
27 static class SessionInfo {
28 String homeDir = null;
29 String curDir = null;
30 public SessionInfo(){
31 homeDir = System.getProperty("user.dir");
32 curDir = homeDir;
33 }
34 }
35
36 static class EchoCommand extends JSTKCommandAdapter {
37 public Object execute(JSTKArgs args) throws JSTKException {
38 StringBuffer msg = new StringBuffer();
39 for (int i = 0; i < args.getNum(); i++){
40 msg.append(args.get(i) + " ");
41 }
42 return new JSTKResult(null, true, msg.toString());
43 }
44 }
45 static class QuitCommand extends JSTKCommandAdapter {
46 public Object execute(JSTKArgs args) throws JSTKException {
47 throw new JSTKQuitException();
48 }
49 }
50
51 static class PWDCommand extends JSTKCommandAdapter {
52 public Object execute(JSTKArgs args) throws JSTKException {
53 String curDir = getCurDir(args);
54 if (curDir == null)
55 return new JSTKResult(null, true, "Session Info. missing or invalid.");
56 return new JSTKResult(null, true, curDir);
57 }
58 }
59
60 static class LSCommand extends JSTKCommandAdapter {
61 public Object execute(JSTKArgs args) throws JSTKException {
62 String curDir = getCurDir(args);
63 if (curDir == null)
64 return new JSTKResult(null, true, "Session Info. missing or invalid.");
65
66 String targetDir = curDir;
67 File file = new File(targetDir);
68 if (!file.isDirectory())
69 return new JSTKResult(null, false, "Not a directory: " + targetDir);
70 String[] fnames = file.list();
71 StringBuffer sb = new StringBuffer();
72 for (int i = 0; i < fnames.length; i++){
73 sb.append(fnames[i] + "\n");
74 }
75 return new JSTKResult(null, true, sb.toString());
76 }
77 }
78
79 static class CDCommand extends JSTKCommandAdapter {
80 public Object execute(JSTKArgs args) throws JSTKException {
81 String curDir = getCurDir(args);
82 String homeDir = getCurDir(args);
83 if (curDir == null || homeDir == null)
84 return new JSTKResult(null, true, "Session Info. missing or invalid.");
85
86 String targetDir = homeDir;
87 if (args.getNum() > 1)
88 return new JSTKResult(null, false, "Specify only one target directory.");
89 else if (args.getNum() == 1)
90 targetDir = args.get(0);
91
92 try {
93 File file = createFile(targetDir, curDir);
94 if (!file.isDirectory())
95 return new JSTKResult(null, false, "Not a directory: " + targetDir);
96 curDir = file.getCanonicalPath();
97 setCurDir(args, curDir);
98 } catch (IOException ioe){
99 throw new JSTKException("cd failed", ioe);
00 }
01 return new JSTKResult(null, true, "Changed Directory To: " + curDir);
02 }
03 }
04
05 static class MkdirCommand extends JSTKCommandAdapter {
06 public Object execute(JSTKArgs args) throws JSTKException {
07 String curDir = getCurDir(args);
08 if (curDir == null)
09 return new JSTKResult(null, true, "Session Info. missing or invalid.");
10
11 String targetDir = null;
12 if (args.getNum() > 1)
13 return new JSTKResult(null, false, "Specify only one directory name.");
14 else if (args.getNum() == 1)
15 targetDir = args.get(0);
16 else
17 return new JSTKResult(null, false, "No directory name specified.");
18
19 boolean result =false;
20 try {
21 File file = createFile(targetDir, curDir);
22 if (file.exists())
23 return new JSTKResult(null, false, "File or directory exists: " + targetDir);
24
25 result = file.mkdirs();
26 } catch (IOException ioe){
27 throw new JSTKException("mkdir failed", ioe);
28 }
29
30 if (result)
31 return new JSTKResult(null, true, "Directory Created: " + targetDir);
32 else
33 return new JSTKResult(null, false, "Cannot create directory: " + targetDir);
34 }
35 }
36
37 static class RMCommand extends JSTKCommandAdapter {
38 public Object execute(JSTKArgs args) throws JSTKException {
39 String curDir = getCurDir(args);
40 if (curDir == null)
41 return new JSTKResult(null, true, "Session Info. missing or invalid.");
42
43 String targetFile = null;
44 if (args.getNum() > 1)
45 return new JSTKResult(null, false, "Specify only one target.");
46 else if (args.getNum() == 1)
47 targetFile = args.get(0);
48 else
49 return new JSTKResult(null, false, "No target specified.");
50
51 boolean result = false;
52 try {
53 File file = createFile(targetFile, curDir);
54 if (!file.exists())
55 return new JSTKResult(null, false, "Target doesn't exist: " + targetFile);
56
57 result = file.delete();
58 } catch (IOException ioe){
59 return new JSTKResult(null, false, "rm failed : " + targetFile + ", Exception: " + ioe);
60 }
61
62 if (result)
63 return new JSTKResult(null, true, "Target removed: " + targetFile);
64 else
65 return new JSTKResult(null, false, "Target ccould not be removed: " + targetFile);
66 }
67 }
68
69 static class CatCommand extends JSTKCommandAdapter {
70 public Object execute(JSTKArgs args) throws JSTKException {
71 String curDir = getCurDir(args);
72 if (curDir == null)
73 return new JSTKResult(null, true, "Session Info. missing or invalid.");
74
75 String targetFile = null;
76 if (args.getNum() > 1)
77 return new JSTKResult(null, false, "Specify only one target.");
78 else if (args.getNum() == 1)
79 targetFile = args.get(0);
80 else
81 return new JSTKResult(null, false, "No target specified.");
82
83 try {
84 File file = createFile(targetFile, curDir);
85 if (!file.exists())
86 return new JSTKResult(null, false, "Target doesn't exist: " + targetFile);
87
88 ByteArrayOutputStream baos = new ByteArrayOutputStream();
89 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
90 int ch;
91 while ((ch = bis.read()) != -1)
92 baos.write(ch);
93
94 return new JSTKResult(null, true, baos.toString());
95 } catch (IOException ioe){
96 throw new JSTKException("cat failed", ioe);
97 }
98 }
99 }
00
01 static class CpCommand extends JSTKCommandAdapter {
02 public Object execute(JSTKArgs args) throws JSTKException {
03 String curDir = getCurDir(args);
04 if (curDir == null)
05 return new JSTKResult(null, true, "Session Info. missing or invalid.");
06
07 String srcFile = null;
08 String dstFile = null;
09 if (args.getNum() > 2)
10 return new JSTKResult(null, false, "Too many arguments.");
11 else if (args.getNum() == 2){
12 srcFile = args.get(0);
13 dstFile = args.get(1);
14 } else
15 return new JSTKResult(null, false, "Insufficient arguments.");
16
17 try {
18 File sFile = createFile(srcFile, curDir);
19 if (!sFile.exists())
20 return new JSTKResult(null, false, "Source doesn't exist: " + srcFile);
21
22 File dFile = createFile(dstFile, curDir);
23 if (dFile.exists())
24 return new JSTKResult(null, false, "Destination exists: " + dstFile);
25
26 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(dFile));
27 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sFile));
28 int ch;
29 while ((ch = bis.read()) != -1)
30 bos.write(ch);
31
32 bis.close();
33 bos.close();
34
35 return new JSTKResult(null, true, "cp: " + srcFile + " --> " + dstFile);
36 } catch (IOException ioe){
37 throw new JSTKException("cp failed", ioe);
38 }
39 }
40 }
41
42 static class ShowCommand extends JSTKCommandAdapter {
43 public Object execute(JSTKArgs args) throws JSTKException {
44 String target = "pdomain";
45 if (args.getNum() > 0)
46 target = args.get(0);
47
48 Class cls = ShowCommand.class;
49 ProtectionDomain pDomain = cls.getProtectionDomain();
50 if (target.equalsIgnoreCase("pdom")){
51 StringBuffer sb = new StringBuffer();
52 CodeSource cs = pDomain.getCodeSource();
53 sb.append("CodeSource: " + cs.toString() + "\n");
54 Principal[] principals = pDomain.getPrincipals();
55 if (principals != null){
56 for (int i = 0; i < principals.length; i++){
57 sb.append("Principal[" + i + "]: " + principals[i] + "\n");
58 }
59 }
60 PermissionCollection permsColl = pDomain.getPermissions();
61 sb.append("Permissions: " + permsColl.toString());
62 return new JSTKResult(null, true, sb.toString());
63 } else if (target.equalsIgnoreCase("perms")){
64 CodeSource cs = pDomain.getCodeSource();
65 PermissionCollection permsColl = Policy.getPolicy().getPermissions(cs);
66 return new JSTKResult(null, true, permsColl.toString());
67 } else if (target.equalsIgnoreCase("cs")){
68 CodeSource cs = pDomain.getCodeSource();
69 return new JSTKResult(null, true, cs.toString());
70 } else if (target.equalsIgnoreCase("classloaders")){
71 StringBuffer sb = new StringBuffer();
72 ClassLoader cl = cls.getClassLoader();
73 int idx = 0;
74 while (cl != null){
75 sb.append("[" + idx + "]ClassLoader: " + cl + "\n");
76 cl = cl.getParent();
77 ++idx;
78 }
79 return new JSTKResult(null, true, sb.toString());
80 }
81 return new JSTKResult(null, false, "unknown target: " + target);
82 }
83 }
84
85 static class WhoAmICommand extends JSTKCommandAdapter {
86 public Object execute(JSTKArgs args) throws JSTKException {
87 AccessControlContext acc = AccessController.getContext();
88 Subject sub = Subject.getSubject(acc);
89 Object[] principals = sub.getPrincipals().toArray();
90 StringBuffer sb = new StringBuffer();
91 for (int i = 0; i < principals.length; i++)
92 sb.append("[" + i + "]" + principals[i].toString());
93
94 return new JSTKResult(null, true, sb.toString());
95 }
96 }
97
98 static class TimeCommand extends JSTKCommandAdapter {
99 public Object execute(JSTKArgs args) throws JSTKException {
00 try {
01 int loopcount = 1000;
02 String loopcountS = args.get("loopcount");
03 if (loopcountS != null)
04 loopcount = Integer.parseInt(loopcountS);
05 if (args.getNum() < 1)
06 return new JSTKResult(null, false, "No command specified.");
07
08 String cmdString = args.get(0);
10 String[] cmdargs = new String[2 + args.getNum() - 1];
11 cmdargs[0] = "-sessionid";
12 cmdargs[1] = args.get("sessionid");
13 for (int i = 1; i < args.getNum(); i++){
14 cmdargs[i+1] = args.get(i);
15 }
16
17 JSTKCommand cmd = (JSTKCommand)cmds.get(cmdString);
18 if (cmd == null) return new JSTKResult(null, false, "Unknown Command: " + cmdString);
20
21 JSTKOptions opts = new JSTKOptions();
22 opts.parse(cmdargs, 0);
23 JSTKResult result = (JSTKResult)cmd.execute(opts);
24
25 long ts = System.currentTimeMillis();
26 for (int i = 0; i < loopcount; i++)
27 cmd.execute(opts);
28 long te = System.currentTimeMillis();
29
30 StringBuffer sb = new StringBuffer();
31 sb.append(result.getText() + "\n");
32 sb.append("Elapsed Time for " + loopcount + " invocations: " + (te - ts) + " millisecs.");
33 return new JSTKResult(null, true, sb.toString());
34 } catch (Exception e){
35 return new JSTKResult(null, false ,"time failed. Exception: " + e);
36 }
37 }
38 }
39
40 public static File createFile(String name, String curDir) throws IOException {
41 File f = new File(name);
42 if (!name.equalsIgnoreCase(f.getCanonicalPath())) f = new File(curDir, name);
44 return f;
45 }
46
47 public static String getCurDir(JSTKArgs args){
48 String sessId = args.get("sessionid");
49 if (sessId == null)
50 return null;
51 SessionInfo sessInfo = (SessionInfo)sessionTable.get(sessId);
52 if (sessInfo == null)
53 return null;
54 return sessInfo.curDir;
55 }
56
57 public static void setCurDir(JSTKArgs args, String curDir){
58 String sessId = args.get("sessionid");
59 if (sessId == null)
60 return;
61 SessionInfo sessInfo = (SessionInfo)sessionTable.get(sessId);
62 if (sessInfo == null)
63 return;
64 sessInfo.curDir = curDir;
65 }
66
67 public static String getHomeDir(JSTKArgs args){
68 String sessId = args.get("sessionid");
69 if (sessId == null)
70 return null;
71 SessionInfo sessInfo = (SessionInfo)sessionTable.get(sessId);
72 if (sessInfo == null)
73 return null;
74 return sessInfo.homeDir;
75 }
76
77 public static final Logger logger = Logger.getLogger("org.jstk.access");
78 static {
79 cmds.put("echo", new EchoCommand());
80 cmds.put("pwd", new PWDCommand());
81 cmds.put("ls", new LSCommand());
82 cmds.put("cd", new CDCommand());
83 cmds.put("md", new MkdirCommand());
84 cmds.put("rm", new RMCommand());
85 cmds.put("cat", new CatCommand());
86 cmds.put("cp", new CpCommand());
87 cmds.put("show", new ShowCommand());
88 cmds.put("whoami", new WhoAmICommand());
89 cmds.put("time", new TimeCommand());
90 cmds.put("quit", new QuitCommand());
91 cmds.put("exit", new QuitCommand());
92 }
93
94 public JSTKShellServer(){
95 super();
96
97 }
98
99 public String progName(){
00 String progName = "java org.jstk.access.JSTKShell";
01 return progName;
02 }
03 public String briefDescription(){
04 return "a minimal shell to demostrate Java Access Control features";
05 }
06
07 public void setSubject(Subject sub){
08 }
10 public String createSession() throws Exception {
11 String sessId = "sess_" + (++curId);
12 SessionInfo sessInfo = new SessionInfo();
13 sessionTable.put(sessId, sessInfo);
14 return sessId;
15 }
16
17 public void destroySession(String sessId) throws Exception {
18 sessionTable.remove(sessId);
19 }
20
21 public String execCommand(String[] args) throws Exception {
22 try {
23 JSTKOptions opts = new JSTKOptions();
24 if (args.length < 1){ return usageString();
26 }
27 String cmdString = args[0];
28 if (cmdString.equals("-h") || cmdString.equals("help") || cmdString.equals("-?")){
29 return usageString();
30 }
31
32 JSTKCommand cmd = (JSTKCommand)cmds.get(cmdString);
33 if (cmd == null){ System.out.println("Unknown Command: " + cmdString);
35 return usageString();
36 }
37
38 if (args.length > 1 && (args[1].equals("-h") || args[1].equals("help") || args[1].equals("-?"))){
39 return cmdUsageString(cmd, cmdString);
40 }
41
42 opts.parse(args, 1);
43
44 JSTKResult result = (JSTKResult)cmd.execute(opts);
45 return result.getText();
46 } catch (SecurityException se){
47 return "Security Violation: " + se;
48 }
49 }
50}