/* * Copyright 2009 NCHOVY * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.krakenapps.console; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.krakenapps.api.AccountManager; import org.krakenapps.api.FunctionKeyEvent; import org.krakenapps.api.ScriptContext; import org.krakenapps.api.ScriptOutputStream; import org.krakenapps.api.ScriptSession; import org.krakenapps.api.FunctionKeyEvent.KeyCode; import org.krakenapps.main.Kraken; import org.krakenapps.script.ScriptContextImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ShellSession { public static final String KRAKEN_PROMPT = "kraken> "; final Logger logger = LoggerFactory.getLogger(ShellSession.class.getName()); private Map<String, Object> attributes; private ScriptContextImpl sc; private String lastChar = null; public ShellSession(ScriptContextImpl scriptContext) { this.attributes = new HashMap<String, Object>(); this.sc = scriptContext; } public ScriptContext getScriptContext() { return sc; } public void printBanner() { sc.getOutputStream().println(Kraken.BANNER); } public void handleMessage(Object message) throws InterruptedException, IOException { if (ignoreLF(message)) return; if (sc.getCurrentScript() == null) processShell(message); else supplyInputToScript(message); } // normalize CRLF private boolean ignoreLF(Object message) { if (!(message instanceof String)) return false; String c = (String) message; if (lastChar != null && lastChar.equals("\r") && c.equals("\n")) { lastChar = c; return true; } lastChar = c; return false; } private void supplyInputToScript(Object message) { if (message instanceof String) { String character = (String) message; sc.transferInput(character.charAt(0)); } else if (message instanceof FunctionKeyEvent) { FunctionKeyEvent keyEvent = (FunctionKeyEvent) message; sc.transferInput(keyEvent); } else { throw new AssertionError("not supported."); } } private void processShell(Object message) throws InterruptedException, IOException { ConsoleController controller = sc.getController(); if (message instanceof FunctionKeyEvent) { FunctionKeyEvent ev = (FunctionKeyEvent) message; // suppress function key while logon if (attributes.get("principal") == null && !ev.isPressed(KeyCode.BACKSPACE)) return; controller.onFunctionKeyPressed(ev); return; } ScriptOutputStream out = sc.getOutputStream(); controller.onCharacterInput((String) message); if (controller.hasLine() == false) return; String line = controller.getLine(); if (attributes.get("principal") == null) { String input = line.replaceAll("\r\n", ""); ScriptSession session = sc.getSession(); if (session.getProperty("kraken.user") == null) { session.setProperty("kraken.user", input); out.print("password: "); sc.turnEchoOff(); return; } else { String name = (String) session.getProperty("kraken.user"); AccountManager accountManager = sc.getAccountManager(); if (accountManager.verifyPassword(name, input)) { setPrincipal(name); sc.turnEchoOn(); out.print("\r\n"); printBanner(); sc.printPrompt(); return; } else { out.print("\r\nAccess denied\r\n"); Thread.sleep(2000); out.print("\r\npassword: "); return; } } } if (line.trim().length() == 0) { sc.printPrompt(); return; } if (handleEmbeddedCommands(out, line)) return; sc.getHistoryManager().pushLine(line); if (logger.isDebugEnabled()) logger.debug("message received: [" + line + "]"); try { runScript(line); return; } catch (InstantiationException e) { out.print("Script instantiation failed.\r\n"); } catch (IllegalAccessException e) { out.print("Script constructor must have a public access.\r\n"); } catch (NullPointerException e) { out.print("syntax error.\r\n"); } sc.printPrompt(); } public void setPrincipal(String name) { attributes.put("principal", name); } private boolean handleEmbeddedCommands(ScriptOutputStream out, String line) throws IOException { line = line.trim(); if ((line.equals("quit") || line.equals("exit"))) sc.quit(); // putty send only CR at ssh mode when you hit enter. if (line.equals("\r") || line.equals("\r\n")) { sc.printPrompt(); return true; } return false; } private void runScript(String line) throws InstantiationException, IllegalAccessException { Thread t = new Thread(new ScriptRunner(sc, line), "Kraken Script Runner [" + line.trim() + "]"); t.start(); } }