Search in sources :

Example 1 with Size

use of org.jline.terminal.Size in project tesb-studio-se by Talend.

the class RuntimeClient method registerSignalHandler.

private static void registerSignalHandler(final Terminal terminal, final PtyCapableChannelSession channel) {
    try {
        Class<?> signalClass = Class.forName("sun.misc.Signal");
        Class<?> signalHandlerClass = Class.forName("sun.misc.SignalHandler");
        // Implement signal handler
        Object signalHandler = Proxy.newProxyInstance(RuntimeClient.class.getClassLoader(), new Class<?>[] { signalHandlerClass }, new InvocationHandler() {

            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Size size = terminal.getSize();
                channel.sendWindowChange(size.getColumns(), size.getRows());
                return null;
            }
        });
        signalClass.getMethod("handle", signalClass, signalHandlerClass).invoke(null, signalClass.getConstructor(String.class).newInstance("WINCH"), signalHandler);
    } catch (Exception e) {
    // Ignore this exception, if the above failed, the signal API is incompatible with what we're expecting
    }
}
Also used : Size(org.jline.terminal.Size) Method(java.lang.reflect.Method) InvocationHandler(java.lang.reflect.InvocationHandler) RuntimeSshException(org.apache.sshd.common.RuntimeSshException)

Example 2 with Size

use of org.jline.terminal.Size in project karaf by apache.

the class SshAction method execute.

@Override
public Object execute() throws Exception {
    if (hostname.indexOf('@') >= 0) {
        if (username == null) {
            username = hostname.substring(0, hostname.indexOf('@'));
        }
        hostname = hostname.substring(hostname.indexOf('@') + 1, hostname.length());
    }
    System.out.println("Connecting to host " + hostname + " on port " + port);
    // If not specified, assume the current user name
    if (username == null) {
        username = (String) this.session.get("USER");
    }
    // If the username was not configured via cli, then prompt the user for the values
    if (username == null) {
        log.debug("Prompting user for login");
        if (username == null) {
            username = session.readLine("Login: ", null);
        }
    }
    SshClient client = SshClient.setUpDefaultClient();
    if (this.session.get(SshAgent.SSH_AUTHSOCKET_ENV_NAME) != null) {
        client.setAgentFactory(KarafAgentFactory.getInstance());
        String agentSocket = this.session.get(SshAgent.SSH_AUTHSOCKET_ENV_NAME).toString();
        client.getProperties().put(SshAgent.SSH_AUTHSOCKET_ENV_NAME, agentSocket);
    }
    KnownHostsManager knownHostsManager = new KnownHostsManager(new File(System.getProperty("user.home"), ".sshkaraf/known_hosts"));
    ServerKeyVerifier serverKeyVerifier = new ServerKeyVerifierImpl(knownHostsManager, quiet);
    client.setServerKeyVerifier(serverKeyVerifier);
    client.setKeyPairProvider(new FileKeyPairProvider());
    log.debug("Created client: {}", client);
    client.setUserInteraction(new UserInteraction() {

        @Override
        public void welcome(ClientSession session, String banner, String lang) {
            System.out.println(banner);
        }

        @Override
        public String[] interactive(ClientSession s, String name, String instruction, String lang, String[] prompt, boolean[] echo) {
            String[] answers = new String[prompt.length];
            try {
                for (int i = 0; i < prompt.length; i++) {
                    answers[i] = session.readLine(prompt[i] + " ", echo[i] ? null : '*');
                }
            } catch (IOException e) {
            }
            return answers;
        }

        @Override
        public boolean isInteractionAllowed(ClientSession session) {
            return true;
        }

        @Override
        public void serverVersionInfo(ClientSession session, List<String> lines) {
        }

        @Override
        public String getUpdatedPassword(ClientSession session, String prompt, String lang) {
            return null;
        }
    });
    client.start();
    try {
        ClientSession sshSession = connectWithRetries(client, username, hostname, port, retries);
        Object oldIgnoreInterrupts = this.session.get(Session.IGNORE_INTERRUPTS);
        try {
            if (password != null) {
                sshSession.addPasswordIdentity(password);
            }
            sshSession.auth().verify();
            System.out.println("Connected");
            this.session.put(Session.IGNORE_INTERRUPTS, Boolean.TRUE);
            StringBuilder sb = new StringBuilder();
            if (command != null) {
                for (String cmd : command) {
                    if (sb.length() > 0) {
                        sb.append(' ');
                    }
                    sb.append(cmd);
                }
            }
            if (sb.length() > 0) {
                ClientChannel channel = sshSession.createChannel("exec", sb.append("\n").toString());
                channel.setIn(new ByteArrayInputStream(new byte[0]));
                channel.setOut(new NoCloseOutputStream(System.out));
                channel.setErr(new NoCloseOutputStream(System.err));
                channel.open().verify();
                channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), 0);
            } else if (session.getTerminal() != null) {
                final ChannelShell channel = sshSession.createShellChannel();
                final org.jline.terminal.Terminal jlineTerminal = (org.jline.terminal.Terminal) session.get(".jline.terminal");
                Attributes attributes = jlineTerminal.enterRawMode();
                try {
                    Map<PtyMode, Integer> modes = new HashMap<>();
                    // Control chars
                    modes.put(PtyMode.VINTR, attributes.getControlChar(ControlChar.VINTR));
                    modes.put(PtyMode.VQUIT, attributes.getControlChar(ControlChar.VQUIT));
                    modes.put(PtyMode.VERASE, attributes.getControlChar(ControlChar.VERASE));
                    modes.put(PtyMode.VKILL, attributes.getControlChar(ControlChar.VKILL));
                    modes.put(PtyMode.VEOF, attributes.getControlChar(ControlChar.VEOF));
                    modes.put(PtyMode.VEOL, attributes.getControlChar(ControlChar.VEOL));
                    modes.put(PtyMode.VEOL2, attributes.getControlChar(ControlChar.VEOL2));
                    modes.put(PtyMode.VSTART, attributes.getControlChar(ControlChar.VSTART));
                    modes.put(PtyMode.VSTOP, attributes.getControlChar(ControlChar.VSTOP));
                    modes.put(PtyMode.VSUSP, attributes.getControlChar(ControlChar.VSUSP));
                    modes.put(PtyMode.VDSUSP, attributes.getControlChar(ControlChar.VDSUSP));
                    modes.put(PtyMode.VREPRINT, attributes.getControlChar(ControlChar.VREPRINT));
                    modes.put(PtyMode.VWERASE, attributes.getControlChar(ControlChar.VWERASE));
                    modes.put(PtyMode.VLNEXT, attributes.getControlChar(ControlChar.VLNEXT));
                    modes.put(PtyMode.VSTATUS, attributes.getControlChar(ControlChar.VSTATUS));
                    modes.put(PtyMode.VDISCARD, attributes.getControlChar(ControlChar.VDISCARD));
                    // Input flags
                    modes.put(PtyMode.IGNPAR, getFlag(attributes, InputFlag.IGNPAR));
                    modes.put(PtyMode.PARMRK, getFlag(attributes, InputFlag.PARMRK));
                    modes.put(PtyMode.INPCK, getFlag(attributes, InputFlag.INPCK));
                    modes.put(PtyMode.ISTRIP, getFlag(attributes, InputFlag.ISTRIP));
                    modes.put(PtyMode.INLCR, getFlag(attributes, InputFlag.INLCR));
                    modes.put(PtyMode.IGNCR, getFlag(attributes, InputFlag.IGNCR));
                    modes.put(PtyMode.ICRNL, getFlag(attributes, InputFlag.ICRNL));
                    modes.put(PtyMode.IXON, getFlag(attributes, InputFlag.IXON));
                    modes.put(PtyMode.IXANY, getFlag(attributes, InputFlag.IXANY));
                    modes.put(PtyMode.IXOFF, getFlag(attributes, InputFlag.IXOFF));
                    // Local flags
                    modes.put(PtyMode.ISIG, getFlag(attributes, LocalFlag.ISIG));
                    modes.put(PtyMode.ICANON, getFlag(attributes, LocalFlag.ICANON));
                    modes.put(PtyMode.ECHO, getFlag(attributes, LocalFlag.ECHO));
                    modes.put(PtyMode.ECHOE, getFlag(attributes, LocalFlag.ECHOE));
                    modes.put(PtyMode.ECHOK, getFlag(attributes, LocalFlag.ECHOK));
                    modes.put(PtyMode.ECHONL, getFlag(attributes, LocalFlag.ECHONL));
                    modes.put(PtyMode.NOFLSH, getFlag(attributes, LocalFlag.NOFLSH));
                    modes.put(PtyMode.TOSTOP, getFlag(attributes, LocalFlag.TOSTOP));
                    modes.put(PtyMode.IEXTEN, getFlag(attributes, LocalFlag.IEXTEN));
                    // Output flags
                    modes.put(PtyMode.OPOST, getFlag(attributes, OutputFlag.OPOST));
                    modes.put(PtyMode.ONLCR, getFlag(attributes, OutputFlag.ONLCR));
                    modes.put(PtyMode.OCRNL, getFlag(attributes, OutputFlag.OCRNL));
                    modes.put(PtyMode.ONOCR, getFlag(attributes, OutputFlag.ONOCR));
                    modes.put(PtyMode.ONLRET, getFlag(attributes, OutputFlag.ONLRET));
                    channel.setPtyModes(modes);
                    channel.setPtyColumns(getTermWidth());
                    channel.setPtyLines(getTermHeight());
                    channel.setAgentForwarding(true);
                    channel.setEnv("TERM", session.getTerminal().getType());
                    Object ctype = session.get("LC_CTYPE");
                    if (ctype != null) {
                        channel.setEnv("LC_CTYPE", ctype.toString());
                    }
                    channel.setIn(new NoCloseInputStream(jlineTerminal.input()));
                    channel.setOut(new NoCloseOutputStream(jlineTerminal.output()));
                    channel.setErr(new NoCloseOutputStream(jlineTerminal.output()));
                    channel.open().verify();
                    SignalListener signalListener = signal -> {
                        try {
                            Size size = jlineTerminal.getSize();
                            channel.sendWindowChange(size.getColumns(), size.getRows());
                        } catch (IOException e) {
                        }
                    };
                    session.getTerminal().addSignalListener(signalListener, Signal.WINCH);
                    try {
                        channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), 0);
                    } finally {
                        session.getTerminal().removeSignalListener(signalListener);
                    }
                } finally {
                    jlineTerminal.setAttributes(attributes);
                }
            } else {
                throw new IllegalStateException("No terminal for interactive ssh session");
            }
        } finally {
            session.put(Session.IGNORE_INTERRUPTS, oldIgnoreInterrupts);
            sshSession.close(false);
        }
    } finally {
        client.stop();
    }
    return null;
}
Also used : SshClient(org.apache.sshd.client.SshClient) Size(org.jline.terminal.Size) Attributes(org.jline.terminal.Attributes) ChannelShell(org.apache.sshd.client.channel.ChannelShell) ClientSession(org.apache.sshd.client.session.ClientSession) ServerKeyVerifier(org.apache.sshd.client.keyverifier.ServerKeyVerifier) IOException(java.io.IOException) Terminal(org.apache.karaf.shell.api.console.Terminal) ClientChannel(org.apache.sshd.client.channel.ClientChannel) FileKeyPairProvider(org.apache.sshd.common.keyprovider.FileKeyPairProvider) NoCloseInputStream(org.apache.sshd.common.util.io.NoCloseInputStream) SignalListener(org.apache.karaf.shell.api.console.SignalListener) ByteArrayInputStream(java.io.ByteArrayInputStream) UserInteraction(org.apache.sshd.client.auth.keyboard.UserInteraction) File(java.io.File) NoCloseOutputStream(org.apache.sshd.common.util.io.NoCloseOutputStream) HashMap(java.util.HashMap) Map(java.util.Map)

Example 3 with Size

use of org.jline.terminal.Size in project karaf by apache.

the class SshTerminal method handleSignal.

protected void handleSignal(org.apache.sshd.server.Signal signal) {
    if (signal == org.apache.sshd.server.Signal.INT) {
        raise(Signal.INT);
    } else if (signal == org.apache.sshd.server.Signal.QUIT) {
        raise(Signal.QUIT);
    } else if (signal == org.apache.sshd.server.Signal.TSTP) {
        raise(Signal.TSTP);
    } else if (signal == org.apache.sshd.server.Signal.CONT) {
        raise(Signal.CONT);
    } else if (signal == org.apache.sshd.server.Signal.WINCH) {
        int w = Integer.valueOf(this.environment.getEnv().get(Environment.ENV_COLUMNS));
        int h = Integer.valueOf(this.environment.getEnv().get(Environment.ENV_LINES));
        setSize(new Size(w, h));
        raise(Signal.WINCH);
    }
}
Also used : Size(org.jline.terminal.Size)

Example 4 with Size

use of org.jline.terminal.Size in project karaf by apache.

the class Main method registerSignalHandler.

private static void registerSignalHandler(final Terminal terminal, final PtyCapableChannelSession channel) {
    try {
        Class<?> signalClass = Class.forName("sun.misc.Signal");
        Class<?> signalHandlerClass = Class.forName("sun.misc.SignalHandler");
        // Implement signal handler
        Object signalHandler = Proxy.newProxyInstance(Main.class.getClassLoader(), new Class<?>[] { signalHandlerClass }, (proxy, method, args) -> {
            Size size = terminal.getSize();
            channel.sendWindowChange(size.getColumns(), size.getRows());
            return null;
        });
        // Register the signal handler, this code is equivalent to:
        // Signal.handle(new Signal("CONT"), signalHandler);
        signalClass.getMethod("handle", signalClass, signalHandlerClass).invoke(null, signalClass.getConstructor(String.class).newInstance("WINCH"), signalHandler);
    } catch (Exception e) {
    // Ignore this exception, if the above failed, the signal API is incompatible with what we're expecting
    }
}
Also used : Size(org.jline.terminal.Size) RuntimeSshException(org.apache.sshd.common.RuntimeSshException) IOException(java.io.IOException)

Aggregations

Size (org.jline.terminal.Size)4 IOException (java.io.IOException)2 RuntimeSshException (org.apache.sshd.common.RuntimeSshException)2 ByteArrayInputStream (java.io.ByteArrayInputStream)1 File (java.io.File)1 InvocationHandler (java.lang.reflect.InvocationHandler)1 Method (java.lang.reflect.Method)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 SignalListener (org.apache.karaf.shell.api.console.SignalListener)1 Terminal (org.apache.karaf.shell.api.console.Terminal)1 SshClient (org.apache.sshd.client.SshClient)1 UserInteraction (org.apache.sshd.client.auth.keyboard.UserInteraction)1 ChannelShell (org.apache.sshd.client.channel.ChannelShell)1 ClientChannel (org.apache.sshd.client.channel.ClientChannel)1 ServerKeyVerifier (org.apache.sshd.client.keyverifier.ServerKeyVerifier)1 ClientSession (org.apache.sshd.client.session.ClientSession)1 FileKeyPairProvider (org.apache.sshd.common.keyprovider.FileKeyPairProvider)1 NoCloseInputStream (org.apache.sshd.common.util.io.NoCloseInputStream)1 NoCloseOutputStream (org.apache.sshd.common.util.io.NoCloseOutputStream)1