CommunicationUtil.cs
上传用户:szltgg
上传日期:2019-05-16
资源大小:604k
文件大小:10k
源码类别:

Telnet服务器

开发平台:

C#

  1. /*
  2. * Copyright (c) 2005 Poderosa Project, All Rights Reserved.
  3. * $Id: CommunicationUtil.cs,v 1.2 2005/04/20 08:45:46 okajima Exp $
  4. */
  5. using System;
  6. using System.Threading;
  7. using System.IO;
  8. using System.Text;
  9. using System.Windows.Forms;
  10. using System.Drawing;
  11. using System.Diagnostics;
  12. using System.Net.Sockets;
  13. using System.Net;
  14. using Granados.SSHC;
  15. using Poderosa.ConnectionParam;
  16. using Poderosa.Connection;
  17. using Poderosa.Config;
  18. using Poderosa.Forms;
  19. using Poderosa.Terminal;
  20. using Poderosa.Toolkit;
  21. using Poderosa.SSH;
  22. using Poderosa.LocalShell;
  23. namespace Poderosa.Communication
  24. {
  25. public class SSHConnector : SocketWithTimeout {
  26. private SSHTerminalParam _param;
  27. private Size _size;
  28. private string _password;
  29. private HostKeyCheckCallback _keycheck;
  30. private ConnectionTag _result;
  31. public SSHConnector(SSHTerminalParam param, Size size, string password, HostKeyCheckCallback keycheck) {
  32. _param = param;
  33. _size = size;
  34. _password = password;
  35. _keycheck = keycheck;
  36. }
  37. protected override string GetHostDescription() {
  38. return "SSH Server";
  39. }
  40. protected override void Negotiate() {
  41. SSHConnectionParameter con = new SSHConnectionParameter();
  42. con.Protocol = _param.Method==ConnectionMethod.SSH1? SSHProtocol.SSH1 : SSHProtocol.SSH2;
  43. con.CheckMACError = GEnv.Options.SSHCheckMAC;
  44. con.UserName = _param.Account;
  45. con.Password = _password;
  46. con.AuthenticationType = _param.AuthType==AuthType.KeyboardInteractive? AuthenticationType.KeyboardInteractive : _param.AuthType==AuthType.Password? AuthenticationType.Password : AuthenticationType.PublicKey;
  47. con.IdentityFile = _param.IdentityFile;
  48. con.TerminalWidth = _size.Width;
  49. con.TerminalHeight = _size.Height;
  50. con.TerminalName = EnumDescAttribute.For(typeof(TerminalType)).GetDescription(_param.TerminalType);
  51.             //con.TerminalName = "xterm";
  52. con.WindowSize = GEnv.Options.SSHWindowSize;
  53. con.PreferableCipherAlgorithms = LocalSSHUtil.ParseCipherAlgorithm(GEnv.Options.CipherAlgorithmOrder);
  54. con.PreferableHostKeyAlgorithms = LocalSSHUtil.ParsePublicKeyAlgorithm(GEnv.Options.HostKeyAlgorithmOrder);
  55. if(_keycheck!=null) con.KeyCheck += new HostKeyCheckCallback(this.CheckKey);
  56. SSHTerminalConnection r = new SSHTerminalConnection(_param, _size.Width, _size.Height);
  57. SSHConnection ssh = SSHConnection.Connect(con, r, _socket);
  58.             
  59. if(ssh!=null) {
  60. if(GEnv.Options.RetainsPassphrase)
  61. _param.Passphrase = _password; //愙懕惉岟帪偺傒僙僢僩
  62. r.FixConnection(ssh);
  63. if(ssh.AuthenticationResult==AuthenticationResult.Success) r.OpenShell();
  64. r.UsingSocks = _socks!=null;
  65. r.SetServerInfo(_param.Host, this.IPAddress);
  66. _result = new ConnectionTag(r);
  67. }
  68. else {
  69. throw new IOException(GEnv.Strings.GetString("Message.SSHConnector.Cancelled"));
  70. }
  71. }
  72. protected override object Result {
  73. get {
  74. return _result;
  75. }
  76. }
  77. private bool CheckKey(SSHConnectionInfo ci) {
  78. SetIgnoreTimeout(); //偙傟偑屇偽傟傞偲偄偆偙偲偼搑拞傑偱SSH偺僱僑僔僄乕僩偑偱偒偰偄傞偺偱僞僀儉傾僂僩偼偟側偄傛偆偵偡傞
  79. return _keycheck(ci);
  80. }
  81. }
  82. internal class TelnetConnector : SocketWithTimeout {
  83. private TelnetTerminalParam _param;
  84. private Size _size;
  85. private ConnectionTag _result;
  86. public TelnetConnector(TelnetTerminalParam param, Size size) {
  87. _param = param;
  88. _size = size;
  89. }
  90. protected override void Negotiate() {
  91. TelnetNegotiator neg = new TelnetNegotiator(_param, _size.Width, _size.Height);
  92. TelnetTerminalConnection r = new TelnetTerminalConnection(_param, neg, new PlainGuevaraSocket(_socket), _size.Width, _size.Height);
  93. r.UsingSocks = _socks!=null;
  94. r.SetServerInfo(_param.Host, this.IPAddress);
  95. _result = new ConnectionTag(r);
  96. }
  97. protected override object Result {
  98. get {
  99. return _result;
  100. }
  101. }
  102. }
  103. public class CommunicationUtil {
  104. public class SilentClient : ISocketWithTimeoutClient {
  105. private AutoResetEvent _event;
  106. private SocketWithTimeout _connector;
  107. private ConnectionTag _result;
  108. private string _errorMessage;
  109. public SilentClient() {
  110. _event = new AutoResetEvent(false);
  111. }
  112. public void SuccessfullyExit(object result) {
  113. _result = (ConnectionTag)result;
  114. //_result.SetServerInfo(((TCPTerminalParam)_result.Param).Host, swt.IPAddress);
  115. _event.Set();
  116. }
  117. public void ConnectionFailed(string message) {
  118. _errorMessage = message;
  119. _event.Set();
  120. }
  121. public void CancelTimer() {
  122. }
  123. public ConnectionTag Wait(SocketWithTimeout swt) {
  124. _connector = swt;
  125. //Form form = GEnv.Frame.AsForm();
  126. //if(form!=null) form.Cursor = Cursors.WaitCursor;
  127. _event.WaitOne(); 
  128. _event.Close();
  129. //if(form!=null) form.Cursor = Cursors.Default;
  130. if(_result==null) {
  131. //GUtil.Warning(GEnv.Frame, _errorMessage);
  132.                     //MessageBox.Show("error");
  133. return null;
  134. }
  135. else
  136. return _result;
  137. }
  138. public IWin32Window GetWindow() {
  139. return GEnv.Frame;
  140. }
  141. }
  142. public static ConnectionTag CreateNewConnection(TerminalParam param) {
  143. if(param is SerialTerminalParam)
  144. return CreateNewSerialConnection(GEnv.Frame, (SerialTerminalParam)param);
  145. else if(param is LocalShellTerminalParam)
  146. return CreateNewLocalShellConnection(GEnv.Frame, (LocalShellTerminalParam)param);
  147. else {
  148. SilentClient s = new SilentClient();
  149. SocketWithTimeout swt = StartNewConnection(s, (TCPTerminalParam)param, null, null);
  150. if(swt==null) return null;
  151. else return s.Wait(swt);
  152. }
  153. }
  154. public static ConnectionTag CreateNewConnection(SSHTerminalParam param, HostKeyCheckCallback keycheck) {
  155. SilentClient s = new SilentClient();
  156. SocketWithTimeout swt = StartNewConnection(s, param, param.Passphrase, keycheck);
  157. if(swt==null) return null;
  158. else return s.Wait(swt);
  159. }
  160. public static SocketWithTimeout StartNewConnection(ISocketWithTimeoutClient client, TCPTerminalParam param, string password, HostKeyCheckCallback keycheck) {
  161. Size sz = GEnv.Frame.TerminalSizeForNextConnection;
  162.             //Size sz = new System.Drawing.Size(528, 316);
  163. SocketWithTimeout swt;
  164. if(param.Method==ConnectionMethod.Telnet) { //Telnet
  165. swt = new TelnetConnector((TelnetTerminalParam)param, sz);
  166. }
  167. else { //SSH 
  168. swt = new SSHConnector((SSHTerminalParam)param, sz, password, keycheck);
  169. }
  170. if(GEnv.Options.UseSocks)
  171. swt.AsyncConnect(client, CreateSocksParam(param.Host, param.Port));
  172. else
  173. swt.AsyncConnect(client, param.Host, param.Port);
  174. return swt;
  175. }
  176. private static Socks CreateSocksParam(string dest_host, int dest_port) {
  177. Socks s = new Socks();
  178. s.DestName = dest_host;
  179. s.DestPort = (short)dest_port;
  180. s.Account = GEnv.Options.SocksAccount;
  181. s.Password = GEnv.Options.SocksPassword;
  182. s.ServerName = GEnv.Options.SocksServer;
  183. s.ServerPort = (short)GEnv.Options.SocksPort;
  184. s.ExcludingNetworks = GEnv.Options.SocksNANetworks;
  185. return s;
  186. }
  187. public static ConnectionTag CreateNewSerialConnection(IWin32Window parent, SerialTerminalParam param) {
  188. bool successful = false;
  189. FileStream strm = null;
  190. try {
  191. string portstr = String.Format("\\.\COM{0}", param.Port);
  192. IntPtr ptr = Win32.CreateFile(portstr, Win32.GENERIC_READ|Win32.GENERIC_WRITE, 0, IntPtr.Zero, Win32.OPEN_EXISTING, Win32.FILE_ATTRIBUTE_NORMAL|Win32.FILE_FLAG_OVERLAPPED, IntPtr.Zero);
  193. if(ptr==Win32.INVALID_HANDLE_VALUE) {
  194. string msg = GEnv.Strings.GetString("Message.CommunicationUtil.FailedToOpenSerial");
  195. int err = Win32.GetLastError();
  196. if(err==2) msg += GEnv.Strings.GetString("Message.CommunicationUtil.NoSuchDevice");
  197. else if(err==5) msg += GEnv.Strings.GetString("Message.CommunicationUtil.DeviceIsBusy");
  198. else msg += "nGetLastError="+ Win32.GetLastError();
  199. throw new Exception(msg);
  200. }
  201. //strm = new FileStream(ptr, FileAccess.Write, true, 8, true);
  202. Win32.DCB dcb = new Win32.DCB();
  203. FillDCB(ptr, ref dcb);
  204. UpdateDCB(ref dcb, param);
  205. if(!Win32.SetCommState(ptr, ref dcb))
  206. throw new Exception(GEnv.Strings.GetString("Message.CommunicationUtil.FailedToConfigSerial"));
  207. Win32.COMMTIMEOUTS timeouts = new Win32.COMMTIMEOUTS();
  208. Win32.GetCommTimeouts(ptr, ref timeouts);
  209. timeouts.ReadIntervalTimeout = 0xFFFFFFFF;
  210. timeouts.ReadTotalTimeoutConstant = 0;
  211. timeouts.ReadTotalTimeoutMultiplier = 0;
  212. timeouts.WriteTotalTimeoutConstant = 100;
  213. timeouts.WriteTotalTimeoutMultiplier = 100;
  214. Win32.SetCommTimeouts(ptr, ref timeouts);
  215. successful = true;
  216. System.Drawing.Size sz = GEnv.Frame.TerminalSizeForNextConnection;
  217. SerialTerminalConnection r = new SerialTerminalConnection(param, ptr, sz.Width, sz.Height);
  218. r.SetServerInfo("COM"+param.Port, null);
  219. return new ConnectionTag(r);
  220. }
  221. catch(Exception ex) {
  222. GUtil.Warning(parent, ex.Message);
  223. return null;
  224. }
  225. finally {
  226. if(!successful && strm!=null) strm.Close();
  227. }
  228. }
  229. public static ConnectionTag CreateNewLocalShellConnection(IWin32Window parent, LocalShellTerminalParam param) {
  230. return LocalShellUtil.PrepareSocket(parent, param);
  231. }
  232. public static bool FillDCB(IntPtr handle, ref Win32.DCB dcb) {
  233. dcb.DCBlength = (uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32.DCB)); //sizeof偔傜偄unsafe偱側偔偰傕巊傢偣偰偔傟傛
  234. return Win32.GetCommState(handle, ref dcb);
  235. }
  236. public static void UpdateDCB(ref Win32.DCB dcb, SerialTerminalParam param) {
  237. dcb.BaudRate = (uint)param.BaudRate;
  238. dcb.ByteSize = param.ByteSize;
  239. dcb.Parity = (byte)param.Parity;
  240. dcb.StopBits = (byte)param.StopBits;
  241. //僼儘乕惂屼丗TeraTerm偺僜乕僗偐傜偪傚偭傁偭偰偒偨
  242. if(param.FlowControl==FlowControl.Xon_Xoff) {
  243. //dcb.fOutX = TRUE;
  244. //dcb.fInX = TRUE;
  245. //dcb傪姰慡偵僐儞僩儘乕儖偡傞僆僾僔儑儞偑昁梫偐傕側
  246. dcb.Misc |= 0x300; //忋婰俀峴偺偐傢傝
  247. dcb.XonLim = 2048; //CommXonLim;
  248. dcb.XoffLim = 2048; //CommXoffLim;
  249. dcb.XonChar = 0x11;
  250. dcb.XoffChar = 0x13;
  251. }
  252. else if(param.FlowControl==FlowControl.Hardware) {
  253. //dcb.fOutxCtsFlow = TRUE;
  254. //dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
  255. dcb.Misc |= 0x4 | 0x2000;
  256. }
  257. }
  258. }
  259. }