0 votes
by (210 points)

I want to use the SSHServer component with custom shell commands which I use already. However based on the authentication event (where I do custom authentication) I want to be able to set an "automcommand"

ie If user xxx login in to SSH I want it to do the autocommand "datetime" which would provide the custom action etc. I dont want the remote session to have to enter the command - in effect replicating a unix system with a custom shell command.

Any way to achieve this?

1 Answer

0 votes
by (144k points)

You can replace the default shell by overriding the "sh" command in ShellCommand event handler. You can then launch a custom action based on the current user. Check out the following sample code:

using System;
using System.IO;
using Rebex;
using Rebex.Net;
using Rebex.Net.Servers;

class Program
{
    // represents user with custom shell
    class CustomShellUser : FileServerUser
    {
        public CustomShellUser(string userName, string password)
            : base(userName, password, ShellType.Empty)
        {
        }

        // custom shell implementation (could be made virtual
        // or changed into Func<SshConsole, int> property
        public int RunCustomShell(SshConsole console)
        {
            console.WriteLine("Welcome to custom shell, {0}!", Name);
            console.WriteLine("Type something...");
            while (true)
            {
                console.Write("> ");
                string input = console.ReadLine();
                if (input == null || input == "exit") break;
                console.WriteLine("You entered '{0}'.", input);
            }
            return 0;
        }
    }

    static void Main(string[] args)
    {
        // load or generate the server key
        string keyFile = "key.pri";
        SshPrivateKey serverKey;
        if (File.Exists(keyFile))
        {
            serverKey = new SshPrivateKey(keyFile);
        }
        else
        {
            serverKey = SshPrivateKey.Generate(SshHostKeyAlgorithm.RSA, 2048);
            serverKey.Save("key.pri", null, SshPrivateKeyFormat.PPK3);
        }

        // set up the server, bind it to port 3322 and add a user
        var server = new FileServer();
        server.LogWriter = new ConsoleLogWriter(LogLevel.Info);
        server.Bind(3322, FileServerProtocol.Shell);
        server.Keys.Add(serverKey);
        server.Users.Add(new CustomShellUser("demo", "password"));

        // register shell command event
        server.ShellCommand += (sender, e) =>
        {
            // for custom shell users, override "sh"
            // (which represents the default shell)
            if (e.Command == "sh")
            {
                var customUser = e.User as CustomShellUser;
                if (customUser != null)
                {
                    e.Action = (args, console) =>
                    {
                        try
                        {
                            return customUser.RunCustomShell(console);
                        }
                        catch (Exception ex)
                        {
                            console.WriteLine("Custom shell failed: {0}", ex);
                            return 255;
                        }
                    };
                }
            }
        };

        // start the server
        server.Start();
        Console.WriteLine("Server started. Press 'Enter' to stop.");
        Console.ReadLine();
    }
}
...