Complete sources for a monero webminer.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

260 lines
9.0 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. // https://github.com/statianzo/Fleck
  2. // The MIT License
  3. // Copyright (c) 2010-2016 Jason Staten
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy of
  5. // this software and associated documentation files (the "Software"), to deal in
  6. // the Software without restriction, including without limitation the rights to
  7. // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  8. // the Software, and to permit persons to whom the Software is furnished to do so,
  9. // subject to the following conditions:
  10. // The above copyright notice and this permission notice shall be included in all
  11. // copies or substantial portions of the Software.
  12. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  14. // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  15. // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  16. // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  17. // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  18. #define __MonoCS__
  19. using System;
  20. using System.Net;
  21. using System.Net.Sockets;
  22. using System.Security.Cryptography.X509Certificates;
  23. using System.Collections.Generic;
  24. using System.Security.Authentication;
  25. using System.Collections.Concurrent;
  26. using System.Threading.Tasks;
  27. using System.Threading;
  28. using Fleck.Helpers;
  29. using System.Collections;
  30. using System.Text;
  31. using System.Text.RegularExpressions;
  32. using System.Security;
  33. using System.Runtime.InteropServices;
  34. using System.IO;
  35. using System.Security.Principal;
  36. using System.Security.AccessControl;
  37. using System.Diagnostics;
  38. using System.Reflection;
  39. namespace Fleck
  40. {
  41. public class WebSocketServer : IWebSocketServer
  42. {
  43. private readonly string _scheme;
  44. private readonly IPAddress _locationIP;
  45. private Action<IWebSocketConnection> _config;
  46. private const int BytesPerLong = 4; // 32 / 8
  47. private const int BitsPerByte = 8;
  48. public WebSocketServer(string location)
  49. {
  50. var uri = new Uri(location);
  51. Port = uri.Port;
  52. Location = location;
  53. _locationIP = ParseIPAddress(uri);
  54. _scheme = uri.Scheme;
  55. var socket = new Socket(_locationIP.AddressFamily, SocketType.Stream, ProtocolType.IP);
  56. if(!MonoHelper.IsRunningOnMono()){
  57. #if __MonoCS__
  58. #else
  59. socket.SetSocketOption(SocketOptionLevel.IPv6, SocketOptionName.IPv6Only, false);
  60. #endif
  61. }
  62. ListenerSocket = new SocketWrapper(socket);
  63. SupportedSubProtocols = new string[0];
  64. }
  65. public ISocket ListenerSocket { get; set; }
  66. public string Location { get; private set; }
  67. public int Port { get; private set; }
  68. public X509Certificate2 Certificate { get; set; }
  69. public SslProtocols EnabledSslProtocols { get; set; }
  70. public IEnumerable<string> SupportedSubProtocols { get; set; }
  71. public bool RestartAfterListenError {get; set; }
  72. public bool IsSecure
  73. {
  74. get { return _scheme == "wss" && Certificate != null; }
  75. }
  76. public void Dispose()
  77. {
  78. ListenerSocket.Dispose();
  79. }
  80. private IPAddress ParseIPAddress(Uri uri)
  81. {
  82. string ipStr = uri.Host;
  83. if (ipStr == "0.0.0.0" ){
  84. return IPAddress.Any;
  85. }else if(ipStr == "[0000:0000:0000:0000:0000:0000:0000:0000]")
  86. {
  87. return IPAddress.IPv6Any;
  88. } else {
  89. try {
  90. return IPAddress.Parse(ipStr);
  91. } catch (Exception ex) {
  92. throw new FormatException("Failed to parse the IP address part of the location. Please make sure you specify a valid IP address. Use 0.0.0.0 or [::] to listen on all interfaces.", ex);
  93. }
  94. }
  95. }
  96. public void Start(Action<IWebSocketConnection> config)
  97. {
  98. var ipLocal = new IPEndPoint(_locationIP, Port);
  99. ListenerSocket.Bind(ipLocal);
  100. ListenerSocket.Listen(100);
  101. Port = ((IPEndPoint)ListenerSocket.LocalEndPoint).Port;
  102. FleckLog.Info(string.Format("Server started at {0} (actual port {1})", Location, Port));
  103. if (_scheme == "wss")
  104. {
  105. if (Certificate == null)
  106. {
  107. FleckLog.Error("Scheme cannot be 'wss' without a Certificate");
  108. return;
  109. }
  110. if (EnabledSslProtocols == SslProtocols.None)
  111. {
  112. EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
  113. //EnabledSslProtocols = SslProtocols.Tls; // changed by wmp
  114. FleckLog.Debug("Using default TLS 1.0 security protocol.");
  115. }
  116. }
  117. ListenForClients();
  118. _config = config;
  119. }
  120. private void TryRestart ()
  121. {
  122. FleckLog.Info ("Listener socket restarting");
  123. try {
  124. ListenerSocket.Dispose ();
  125. var socket = new Socket (_locationIP.AddressFamily, SocketType.Stream, ProtocolType.IP);
  126. ListenerSocket = new SocketWrapper (socket);
  127. Start (_config);
  128. FleckLog.Info ("Listener socket restarted");
  129. } catch (Exception ex) {
  130. FleckLog.Error ("Listener socket could not be restarted", ex);
  131. }
  132. }
  133. private void ListenForClients ()
  134. {
  135. ManualResetEvent acceptDone = new ManualResetEvent (false);
  136. bool running = true;
  137. Task.Run (() => {
  138. while (running) {
  139. acceptDone.Reset ();
  140. var task = ListenerSocket.Accept(
  141. s => {
  142. running = (s != null);
  143. acceptDone.Set ();
  144. OnClientConnect (s); },
  145. e => { FleckLog.Error ("Error while listening for new clients", e);
  146. if (RestartAfterListenError) TryRestart ();
  147. running = false; acceptDone.Set (); }
  148. );
  149. task.ContinueWith((t) => FleckLog.Warn ("Error during client connect", t.Exception),
  150. TaskContinuationOptions.OnlyOnFaulted);
  151. acceptDone.WaitOne ();
  152. }
  153. });
  154. }
  155. private void OnClientConnect(ISocket clientSocket)
  156. {
  157. if (clientSocket == null) return; // socket closed
  158. // experimental removed by wmp
  159. //FleckLog.Debug(String.Format("Client connected from {0}:{1}", clientSocket.RemoteIpAddress, clientSocket.RemotePort.ToString()));
  160. //Console.WriteLine(String.Format("Client connected from {0}:{1}", clientSocket.RemoteIpAddress, clientSocket.RemotePort.ToString()));
  161. string rep = string.Empty;
  162. bool failed = false;
  163. try {
  164. rep = clientSocket.RemoteIpAddress;
  165. Console.WriteLine("Connecting: " + rep);
  166. }
  167. catch{
  168. Console.WriteLine ("Started but IP not available.");
  169. failed = true;
  170. }
  171. ListenForClients();
  172. if (failed) {
  173. try{ clientSocket.Close (); }catch{}
  174. try{ clientSocket.Stream.Close();}catch{}
  175. try{ clientSocket.Dispose ();}catch{}
  176. return;
  177. }
  178. WebSocketConnection connection = null;
  179. connection = new WebSocketConnection(
  180. clientSocket,
  181. _config,
  182. bytes => RequestParser.Parse(bytes, _scheme),
  183. r => HandlerFactory.BuildHandler(r,
  184. s => connection.OnMessage(s),
  185. connection.Close,
  186. b => connection.OnBinary(b),
  187. b => connection.OnPing(b),
  188. b => connection.OnPong(b)),
  189. s => SubProtocolNegotiator.Negotiate(SupportedSubProtocols, s));
  190. if (IsSecure)
  191. {
  192. FleckLog.Debug("Authenticating Secure Connection");
  193. clientSocket
  194. .Authenticate(Certificate,
  195. EnabledSslProtocols,
  196. () =>
  197. {
  198. Console.WriteLine("Authenticated {0}", rep);
  199. Server.Firewall.Update(rep, Server.Firewall.UpdateEntry.AuthSuccess);
  200. connection.StartReceiving();
  201. }
  202. ,e =>
  203. {
  204. FleckLog.Warn("Failed to Authenticate " + rep, e);
  205. // here we could add connection.Close() ! wmp
  206. Server.Firewall.Update(rep, Server.Firewall.UpdateEntry.AuthFailure);
  207. connection.Close();
  208. });
  209. }
  210. else
  211. {
  212. Server.Firewall.Update(rep, Server.Firewall.UpdateEntry.AuthSuccess);
  213. connection.StartReceiving();
  214. }
  215. }
  216. }
  217. }