Yes, a vote is already going on to start the SSH subproject.
On Sun, Nov 23, 2008 at 8:19 AM, Jason Dillon <[EMAIL PROTECTED]> wrote:
> On Nov 22, 2008, at 6:48 PM, Guillaume Nodet wrote:
>>>
>>> <snip>
>>> Bliss:Applications jason$ ssh localhost -p 8081
>>> [EMAIL PROTECTED]'s password:
>>> channel_by_id: 1: bad id: channel free
>>> channel_input_success_failure: 1: unknown
>>> channel_by_id: 1: bad id: channel free
>>> channel_input_success_failure: 1: unknown
>>> </snip>
>>>
>>> This is from "OpenSSH_5.1p1, OpenSSL 0.9.7l 28 Sep 2006" on Mac OS X. It
>>> does connect and seems to work well. Though seems to not handle sending
>>> over exceptions, like when a command is not resolved. But I might look
>>> into
>>> that some more later today.
>>
>> Not sure what those lines mean. When I connect using OpenSSH and
>> launch a bad command in ServiceMix, I can see the usual output from
>> gshell on stderr with the ansi colors.
>
> I will investigate more... I did not see the exception spat out on the
> client when entering a bad command... perhaps that is because of the above
> msgs?
>
>> There are still lots of things to do, but i think i could release a
>> 0.1 very soon.
>> Btw, this project should soon move into Apache as a Mina subproject,
>> but I will do a release before that at google so that we can embed it.
>
> Have you talked to the mina folks about it? Anyways, I can't stop saying
> how thrilled I am about this. You rock! Needless to say next time we meet
> up I'm gonna buy you all the beer you can drink ;-)
>
> --jason
>
>
>>
>>> Your thoughts?
>>>
>>> --jason
>>>
>>>
>>> On Nov 13, 2008, at 5:58 AM, Guillaume Nodet wrote:
>>>
>>>> I've just done a real quick prototype to plug into smx kernel and I've
>>>> been able to log in into smx kernel using an ssh client and issue a
>>>> few commands.
>>>> Following is the class that does everything and the spring config to
>>>> start the ssh server.
>>>> The BogusPasswordAuthenticator is a dummy class which I pasted below
>>>> too.
>>>>
>>>> Notice the use of stream filters to convert CR / CRLF stuff. I think
>>>> this is because both sshd and the geronimo gshell do not handle well
>>>> the pty request and/or VT100 stuff. But I'm still not sure where the
>>>> conversion should happen exactly.
>>>>
>>>> Also note that i've redefined the ConsoleErrorHandlerImpl, because the
>>>> default one uses the application.getIO() for displaying errors so they
>>>> are not available remotely.
>>>>
>>>> Let me know what you think, but it basically makes the whole remote
>>>> bits of gshell unused.
>>>> I have not implemented the ssh command which should be easy using jsch
>>>> lib.
>>>>
>>>> Let me know if / how I can help you with that bits.
>>>>
>>>> ==================================================
>>>> package org.apache.servicemix.kernel.gshell.core.sshd;
>>>>
>>>> import com.google.code.sshd.PasswordAuthenticator;
>>>>
>>>> public class BogusPasswordAuthenticator implements PasswordAuthenticator
>>>> {
>>>>
>>>> public Object authenticate(String username, String password) {
>>>> return (username != null && username.equals(password)) ?
>>>> username : null;
>>>> }
>>>> }
>>>>
>>>>
>>>> ==================================================
>>>> <bean name="sshServer" class="com.google.code.sshd.SshServer"
>>>> init-method="start" destroy-method="stop">
>>>> <property name="port" value="8000" />
>>>> <property name="shellFactory">
>>>> <bean
>>>>
>>>> class="org.apache.servicemix.kernel.gshell.core.sshd.GShellShellFactory">
>>>> <property name="branding" ref="branding" />
>>>> <property name="completers">
>>>> <list>
>>>> <ref bean="commandsCompleter"/>
>>>> <ref bean="aliasNameCompleter"/>
>>>> </list>
>>>> </property>
>>>> <property name="executor" ref="commandLineExecutor" />
>>>> <property name="history">
>>>> <bean
>>>> class="org.apache.geronimo.gshell.wisdom.shell.HistoryImpl">
>>>> <constructor-arg ref="application"/>
>>>> </bean>
>>>> </property>
>>>> <property name="prompter">
>>>> <bean
>>>> class="org.apache.geronimo.gshell.wisdom.shell.ConsolePrompterImpl">
>>>> <constructor-arg ref="application"/>
>>>> </bean>
>>>> </property>
>>>> </bean>
>>>> </property>
>>>> <property name="hostKeyProvider">
>>>> <bean class="com.google.code.sshd.hostkeys.FileHostKeyProvider">
>>>> <constructor-arg>
>>>> <list>
>>>> <value>${hostKey}</value>
>>>> </list>
>>>> </constructor-arg>
>>>> </bean>
>>>> </property>
>>>> <property name="passwordAuthenticator">
>>>> <!-- TODO: provide real authentication -->
>>>> <bean
>>>>
>>>>
>>>> class="org.apache.servicemix.kernel.gshell.core.sshd.BogusPasswordAuthenticator"
>>>> />
>>>> </property>
>>>> <!-- Do not use public keys for now
>>>> <property name="publickeyAuthenticator">
>>>> <bean class="com.google.code.sshd.BogusPublickeyAuthenticator"
>>>> />
>>>> </property>
>>>> -->
>>>> <!-- Standard properties -->
>>>> <property name="channelFactories">
>>>> <list>
>>>> <bean
>>>> class="com.google.code.sshd.channel.ChannelSession$Factory" />
>>>> </list>
>>>> </property>
>>>> <property name="cipherFactories">
>>>> <list>
>>>> <bean class="com.google.code.sshd.cipher.AES128CBC$Factory"
>>>> />
>>>> <bean
>>>> class="com.google.code.sshd.cipher.TripleDESCBC$Factory" />
>>>> <bean
>>>> class="com.google.code.sshd.cipher.BlowfishCBC$Factory" />
>>>> <bean class="com.google.code.sshd.cipher.AES192CBC$Factory"
>>>> />
>>>> <bean class="com.google.code.sshd.cipher.AES256CBC$Factory"
>>>> />
>>>> </list>
>>>> </property>
>>>> <property name="compressionFactories">
>>>> <list>
>>>> <bean
>>>> class="com.google.code.sshd.compression.CompressionNone$Factory" />
>>>> </list>
>>>> </property>
>>>> <property name="keyExchangeFactories">
>>>> <list>
>>>> <bean class="com.google.code.sshd.kex.DHG1$Factory" />
>>>> </list>
>>>> </property>
>>>> <property name="macFactories">
>>>> <list>
>>>> <bean class="com.google.code.sshd.mac.HMACMD5$Factory" />
>>>> <bean class="com.google.code.sshd.mac.HMACSHA1$Factory" />
>>>> <bean class="com.google.code.sshd.mac.HMACMD596$Factory" />
>>>> <bean class="com.google.code.sshd.mac.HMACSHA196$Factory" />
>>>> </list>
>>>> </property>
>>>> <property name="randomFactory">
>>>> <bean class="com.google.code.sshd.random.JceRandom$Factory" />
>>>> </property>
>>>> <property name="userAuthFactories">
>>>> <list>
>>>> <bean
>>>> class="com.google.code.sshd.auth.UserAuthPublicKey$Factory" />
>>>> <bean
>>>> class="com.google.code.sshd.auth.UserAuthPassword$Factory" />
>>>> </list>
>>>> </property>
>>>> <property name="signatureFactories">
>>>> <list>
>>>> <bean
>>>> class="com.google.code.sshd.signature.SignatureDSA$Factory" />
>>>> <bean
>>>> class="com.google.code.sshd.signature.SignatureRSA$Factory" />
>>>> </list>
>>>> </property>
>>>> </bean>
>>>>
>>>>
>>>>
>>>> ===================================================
>>>> package org.apache.servicemix.kernel.gshell.core.sshd;
>>>>
>>>> import java.util.Map;
>>>> import java.util.List;
>>>> import java.io.OutputStream;
>>>> import java.io.InputStream;
>>>> import java.io.Closeable;
>>>> import java.io.IOException;
>>>>
>>>> import com.google.code.sshd.ShellFactory;
>>>> import com.google.code.sshd.shell.CrLfFilterInputStream;
>>>> import org.apache.geronimo.gshell.shell.ShellContext;
>>>> import org.apache.geronimo.gshell.io.IO;
>>>> import org.apache.geronimo.gshell.command.Variables;
>>>> import org.apache.geronimo.gshell.console.Console;
>>>> import org.apache.geronimo.gshell.console.JLineConsole;
>>>> import org.apache.geronimo.gshell.console.completer.AggregateCompleter;
>>>> import org.apache.geronimo.gshell.notification.ExitNotification;
>>>> import org.apache.geronimo.gshell.notification.ErrorNotification;
>>>> import org.apache.geronimo.gshell.application.model.Branding;
>>>> import org.apache.geronimo.gshell.commandline.CommandLineExecutor;
>>>> import org.apache.geronimo.gshell.ansi.AnsiRenderer;
>>>> import org.slf4j.LoggerFactory;
>>>> import org.slf4j.Logger;
>>>> import jline.History;
>>>> import jline.Completor;
>>>>
>>>> public class GShellShellFactory implements ShellFactory {
>>>>
>>>> private Logger logger = LoggerFactory.getLogger(getClass());
>>>> private Branding branding;
>>>> private Console.Prompter prompter;
>>>> private CommandLineExecutor executor;
>>>> private History history;
>>>> private List<Completor> completers;
>>>>
>>>> public Branding getBranding() {
>>>> return branding;
>>>> }
>>>>
>>>> public void setBranding(Branding branding) {
>>>> this.branding = branding;
>>>> }
>>>>
>>>> public Console.Prompter getPrompter() {
>>>> return prompter;
>>>> }
>>>>
>>>> public void setPrompter(Console.Prompter prompter) {
>>>> this.prompter = prompter;
>>>> }
>>>>
>>>> public CommandLineExecutor getExecutor() {
>>>> return executor;
>>>> }
>>>>
>>>> public void setExecutor(CommandLineExecutor executor) {
>>>> this.executor = executor;
>>>> }
>>>>
>>>> public History getHistory() {
>>>> return history;
>>>> }
>>>>
>>>> public void setHistory(History history) {
>>>> this.history = history;
>>>> }
>>>>
>>>> public List<Completor> getCompleters() {
>>>> return completers;
>>>> }
>>>>
>>>> public void setCompleters(List<Completor> completers) {
>>>> this.completers = completers;
>>>> }
>>>>
>>>> public Shell createShell() {
>>>> return new ShellImpl();
>>>> }
>>>>
>>>> public class ShellImpl implements ShellFactory.DirectShell,
>>>> org.apache.geronimo.gshell.shell.Shell {
>>>>
>>>> private InputStream in;
>>>> private OutputStream out;
>>>> private OutputStream err;
>>>> private IO io;
>>>> private Variables variables;
>>>> private ShellContext context;
>>>> private boolean closed;
>>>>
>>>> public ShellImpl() {
>>>> }
>>>>
>>>> public void setInputStream(InputStream in) {
>>>> this.in = in;
>>>> }
>>>>
>>>> public void setOutputStream(OutputStream out) {
>>>> this.out = out;
>>>> }
>>>>
>>>> public void setErrorStream(OutputStream err) {
>>>> this.err = err;
>>>> }
>>>>
>>>> public void start(Map<String,String> env) throws Exception {
>>>> this.io = new IO(new CrLfFilterInputStream(in, "IN: ", logger),
>>>> new LfToCrLfFilterOutputStream(out,
>>>> "OUT:", logger),
>>>> new LfToCrLfFilterOutputStream(err,
>>>> "ERR:", logger),
>>>> false);
>>>> this.variables = new Variables((Map) env);
>>>> this.context = new ShellContext() {
>>>> public org.apache.geronimo.gshell.shell.Shell getShell() {
>>>> return ShellImpl.this;
>>>> }
>>>> public IO getIo() {
>>>> return ShellImpl.this.io;
>>>> }
>>>> public Variables getVariables() {
>>>> return ShellImpl.this.variables;
>>>> }
>>>> };
>>>> new Thread() {
>>>> public void run() {
>>>> try {
>>>> ShellImpl.this.run();
>>>> } catch (Exception e) {
>>>> e.printStackTrace();
>>>> } finally {
>>>> close();
>>>> }
>>>> }
>>>> }.start();
>>>> }
>>>>
>>>> public boolean isAlive() {
>>>> return !closed;
>>>> }
>>>>
>>>> public int exitValue() {
>>>> if (!closed) {
>>>> throw new IllegalThreadStateException();
>>>> }
>>>> return 0;
>>>> }
>>>>
>>>> public void destroy() {
>>>> close();
>>>> }
>>>>
>>>> public ShellContext getContext() {
>>>> return context;
>>>> }
>>>>
>>>> public Object execute(String line) throws Exception {
>>>> return executor.execute(getContext(), line);
>>>> }
>>>>
>>>> public Object execute(String command, Object[] args) throws
>>>> Exception {
>>>> return executor.execute(getContext(), args);
>>>> }
>>>>
>>>> public Object execute(Object... args) throws Exception {
>>>> return executor.execute(getContext(), args);
>>>> }
>>>>
>>>> public boolean isOpened() {
>>>> return !closed;
>>>> }
>>>>
>>>> public void close() {
>>>> closed = true;
>>>> close(in);
>>>> close(out);
>>>> close(err);
>>>> }
>>>>
>>>> public boolean isInteractive() {
>>>> return false;
>>>> }
>>>>
>>>> public void run(Object... args) throws Exception {
>>>> Console.Executor executor = new Console.Executor() {
>>>> public Result execute(final String line) throws Exception {
>>>> assert line != null;
>>>> try {
>>>> ShellImpl.this.execute(line);
>>>> }
>>>> catch (ExitNotification n) {
>>>> return Result.STOP;
>>>> }
>>>> return Result.CONTINUE;
>>>> }
>>>> };
>>>>
>>>> IO io = getContext().getIo();
>>>>
>>>> // Setup the console runner
>>>> JLineConsole console = new JLineConsole(executor, io);
>>>> console.setPrompter(getPrompter());
>>>> console.setErrorHandler(new ConsoleErrorHandlerImpl(io));
>>>> console.setHistory(getHistory());
>>>> if (completers != null) {
>>>> // Have to use aggregate here to get the completion
>>>> list to update properly
>>>> console.addCompleter(new AggregateCompleter(completers));
>>>> }
>>>> console.run();
>>>> }
>>>>
>>>> private void close(Closeable c) {
>>>> try {
>>>> c.close();
>>>> } catch (IOException e) {
>>>> // Ignore
>>>> }
>>>> }
>>>>
>>>> }
>>>>
>>>> public static class ConsoleErrorHandlerImpl implements
>>>> Console.ErrorHandler {
>>>> private final Logger log = LoggerFactory.getLogger(getClass());
>>>>
>>>> private final IO io;
>>>>
>>>> private AnsiRenderer renderer = new AnsiRenderer();
>>>>
>>>> public ConsoleErrorHandlerImpl(final IO io) {
>>>> assert io != null;
>>>> this.io = io;
>>>> }
>>>>
>>>> public Result handleError(final Throwable error) {
>>>> assert error != null;
>>>>
>>>> displayError(error);
>>>>
>>>> return Result.CONTINUE;
>>>> }
>>>>
>>>> private void displayError(final Throwable error) {
>>>> assert error != null;
>>>>
>>>> // Decode any error notifications
>>>> Throwable cause = error;
>>>> if (error instanceof ErrorNotification) {
>>>> cause = error.getCause();
>>>> }
>>>>
>>>> //
>>>> // TODO: Use the Render API
>>>> //
>>>>
>>>> // Spit out the terse reason why we've failed
>>>> io.err.print("@|bold,red ERROR| ");
>>>> io.err.print(cause.getClass().getSimpleName());
>>>> io.err.println(": @|bold,red " + cause.getMessage() + "|");
>>>>
>>>> // Determine if the stack trace flag is set
>>>> String stackTraceProperty =
>>>> System.getProperty("gshell.show.stacktrace");
>>>> boolean stackTraceFlag = false;
>>>> if (stackTraceProperty != null) {
>>>> stackTraceFlag = stackTraceProperty.trim().equals("true");
>>>> }
>>>>
>>>> if (io.isDebug()) {
>>>> // If we have debug enabled then skip the fancy bits
>>>> below, and log the full error, don't decode shit
>>>> log.debug(error.toString(), error);
>>>> }
>>>> else if (io.isVerbose() || stackTraceFlag) {
>>>> // Render a fancy ansi colored stack trace
>>>> StackTraceElement[] trace = cause.getStackTrace();
>>>> StringBuilder buff = new StringBuilder();
>>>>
>>>> //
>>>> // TODO: Move this to helper in gshell-ansi
>>>> //
>>>>
>>>> for (StackTraceElement e : trace) {
>>>> buff.append(" @|bold at| ").
>>>> append(e.getClassName()).
>>>> append(".").
>>>> append(e.getMethodName()).
>>>> append(" (@|bold ");
>>>>
>>>> buff.append(e.isNativeMethod() ? "Native Method" :
>>>> (e.getFileName() != null &&
>>>> e.getLineNumber() != -1 ? e.getFileName() + ":" + e.getLineNumber() :
>>>> (e.getFileName() != null ?
>>>> e.getFileName() : "Unknown Source")));
>>>>
>>>> buff.append("|)");
>>>>
>>>> //
>>>> // FIXME: This does not properly display the full
>>>> exception detail when cause contains nested exceptions
>>>> //
>>>>
>>>> io.err.println(buff);
>>>>
>>>> buff.setLength(0);
>>>> }
>>>> }
>>>> io.err.flush();
>>>> }
>>>> }
>>>>
>>>> }
>>>>
>>>>
>>>> On Tue, Nov 11, 2008 at 8:07 AM, Jason Dillon <[EMAIL PROTECTED]>
>>>> wrote:
>>>>>
>>>>> How does one hook up GShell to use this stuff?
>>>>>
>>>>> --jason
>>>>>
>>>>>
>>>>> On Nov 7, 2008, at 4:22 AM, Guillaume Nodet wrote:
>>>>>
>>>>>> Over the past days, I've been working on a implementing a SSH server
>>>>>> in java to replace to gshell remoting bits.
>>>>>> The project is currently hosted at google code:
>>>>>> http://code.google.com/p/sshd/
>>>>>>
>>>>>> This project is based on Mina and the current status is that the ssh
>>>>>> protocol is in a working state, but there are still a lots of things
>>>>>> to iron.
>>>>>> I've been able to connect using openssh 5.0 and 5.1 and also jsch
>>>>>> (from which i borrowed from code btw) and launch an /bin/sh shell and
>>>>>> issue a few commands.
>>>>>> I'd be happy if any committer is interested to work on that to give
>>>>>> him commits rights on the project.
>>>>>>
>>>>>> --
>>>>>> Cheers,
>>>>>> Guillaume Nodet
>>>>>> ------------------------
>>>>>> Blog: http://gnodet.blogspot.com/
>>>>>> ------------------------
>>>>>> Open Source SOA
>>>>>> http://fusesource.com
>>>>>
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Cheers,
>>>> Guillaume Nodet
>>>> ------------------------
>>>> Blog: http://gnodet.blogspot.com/
>>>> ------------------------
>>>> Open Source SOA
>>>> http://fusesource.com
>>>
>>>
>>
>>
>>
>> --
>> Cheers,
>> Guillaume Nodet
>> ------------------------
>> Blog: http://gnodet.blogspot.com/
>> ------------------------
>> Open Source SOA
>> http://fusesource.com
>
>
--
Cheers,
Guillaume Nodet
------------------------
Blog: http://gnodet.blogspot.com/
------------------------
Open Source SOA
http://fusesource.com