123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- using AspNetTools;
- using FxSsh;
- using FxSsh.Services;
- using MiniTerm;
- using System;
- using System.Configuration;
- using System.IO;
- using System.Net;
- using System.Net.Sockets;
- using System.Reflection;
- using System.Web;
- namespace WebTerminalServer
- {
- public class SshWsModule : IHttpModule
- {
- private SshServer _server;
- private IPEndPoint _listenEndPoint;
- private static void Log(string info)
- {
- File.AppendAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data", "logs.log"), info + Environment.NewLine);
- }
- public void Init(HttpApplication context)
- {
- Log("SshWsModule Init, OS:" + Environment.OSVersion.ToString());
- AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
- {
- Log(args.ExceptionObject?.ToString());
- };
- //Create ssh server with available port
- _server = new SshServer(new StartingInfo(IPAddress.Loopback, 0, "SSH-2"));
- _server.AddHostKey("ssh-rsa", ConfigurationManager.AppSettings["SshHostKey"]);
- _server.ConnectionAccepted += (s2, e2) =>
- {
- e2.ServiceRegistered += (s1, e1) =>
- {
- if (e1 is UserauthService)
- {
- var service = (UserauthService)e1;
- service.Userauth += (s, e) =>
- {
- e.Result = true;
- };
- }
- else if (e1 is ConnectionService service)
- {
- int w = 0, h = 0;
- Terminal terminal = null;
- service.EnvReceived += (s, e) => Console.WriteLine("Received environment variable {0}:{1}", e.Name, e.Value); ;
- service.PtyReceived += (s, e) =>
- {
- w = (int)e.WidthChars;
- h = (int)e.HeightRows;
- };
- service.WindowChange += (sender, args) =>
- {
- terminal?.ChangeWindowSize((short)args.WidthColumns, (short)args.HeightRows);
- };
- service.CommandOpened += (s, e) =>
- {
- Console.WriteLine($"Channel {e.Channel.ServerChannelId} runs {e.ShellType}: \"{e.CommandText}\".");
- var allow = true; // func(e.ShellType, e.CommandText, e.AttachedUserauthArgs);
- if (!allow) return;
- if (e.ShellType == "shell")
- {
- // requirements: Windows 10 RedStone 5, 1809
- // also, you can call powershell.exe
- Log("Pending Create Terminal");
- try
- {
- terminal = new Terminal("cmd.exe", w, h);
- }
- catch (Exception exception)
- {
- Log(exception.ToString());
- return;
- }
- Log("Terminal Created");
- e.Channel.DataReceived += (ss, ee) => terminal.OnInput(ee);
- e.Channel.CloseReceived += (ss, ee) => terminal.OnClose();
- terminal.DataReceived += (ss, ee) => e.Channel.SendData(ee);
- terminal.CloseReceived += (ss, ee) => e.Channel.SendClose(ee);
- terminal.Run();
- }
- };
- }
- };
- };
- _server.Start();
- var field = _server.GetType().GetField("_listenser", BindingFlags.Instance | BindingFlags.NonPublic);
- var listener = (TcpListener)field.GetValue(_server);
- _listenEndPoint = (IPEndPoint)listener.Server.LocalEndPoint;
- context.PostMapRequestHandler += delegate
- {
- WebSocketForwardModule.ForwardCurrentContext("terminal", ConfigurationManager.AppSettings["PassCode"], _listenEndPoint);
- };
- }
- public void Dispose()
- {
- _server?.Stop();
- }
- }
- }
|