public static void ChangeTunnelStatus(TunnelStatuses tunnelStatus, bool saveTunnelStatus = true) { TunnelHelper.CurrentTunnelStatus = tunnelStatus; ServiceSettings serviceSettings = SettingsHelper.GetSettings(); if (saveTunnelStatus) { Settings settings = new Settings(); settings.CurrentTunnelStatus = (int)tunnelStatus; settings.Save(); } if (tunnelStatus == TunnelStatuses.Started) { WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog("Plink Starting", DateTime.Now), true); if (ProcessHelper.StartPlink()) { TunnelPingHelper.OpenTunnelPingListener(); WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog("Plink Started: " + ProcessHelper.GetPlinkArguments(serviceSettings), DateTime.Now), true); } else { ChangeTunnelStatus(TunnelStatuses.Paused); } } else { WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog("Plink Stopping", DateTime.Now), true); TunnelPingHelper.CloseTunnelPingListener(); ProcessHelper.StopPlink(); } WcfServerHelper.BroadcastRemoteCallback(x => x.TunnelStatusChanged(tunnelStatus), true); }
public static void CloseTunnelPingListener() { if (TunnelPingHelper.TunnelValidatorRunning) { TunnelPingHelper.TunnelValidatorRunning = false; WcfServerHelper.BroadcastRemoteCallback((x) => x.EventToLog("Tunnel Validation Closing", DateTime.Now), true); try { if (_pingTunnelTimer != null && _pingTunnelTimer.Enabled) { _pingTunnelTimer.Stop(); _pingTunnelTimer.Dispose(); } if (_validationListener != null) { _validationListener.Stop(); } } catch (Exception ex) { WcfServerHelper.BroadcastRemoteCallback((x) => x.EventToLog(ex.Message + " ::: " + ex.StackTrace, DateTime.Now), true); } } }
private static void HandleFailedTunnelPing() { WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog("Tunnel ping failed! (consecutive failures: " + TunnelValidatorConsecutiveFailures.ToString() + ")", DateTime.Now)); TunnelValidatorLastPingSuccessful = false; if (TunnelValidatorConsecutiveFailures < 3) { CloseTunnelPingListener(); WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog("Restarting Tunnel Validation", DateTime.Now)); Thread.Sleep(800); OpenTunnelPingListener(); } else if (TunnelValidatorConsecutiveFailures < 6) { WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog("Restarting Plink.exe", DateTime.Now)); Thread.Sleep(1000); ProcessHelper.StopPlink(); } else { WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog("Restarting Plink.exe AND Tunnel Validation", DateTime.Now)); CloseTunnelPingListener(); Thread.Sleep(500); ProcessHelper.StopPlink(); Thread.Sleep(1500); OpenTunnelPingListener(); } TunnelValidatorConsecutiveFailures++; }
public static void PingClient() { WcfServerHelper.BroadcastRemoteCallback(x => x.Ping( ProcessHelper.PlinkRunning, (TunnelPingHelper.TunnelValidatorLastPingSuccessful && TunnelPingHelper.TunnelValidatorRunning), TunnelPingHelper.TunnelValidatorLastSuccessfulPingTime)); WcfServerHelper.LastPingToClient = DateTime.Now; }
public static void SendTunnelPing() { Task.Factory.StartNew(() => { try { ServiceSettings serviceSettings = SettingsHelper.GetSettings(); TcpClient tcpClient = new TcpClient("localhost", serviceSettings.TunnelValidationLocalPort); using (NetworkStream stream = tcpClient.GetStream()) { byte[] sendData = Encoding.ASCII.GetBytes("-111-"); stream.Write(sendData, 0, sendData.Length); byte[] responseData = new byte[32]; if (stream.CanRead) { int bytesReceived = stream.Read(responseData, 0, responseData.Length); string responseString = Encoding.ASCII.GetString(responseData, 0, bytesReceived); if (responseString.Trim() == "-222-") { WcfServerHelper.BroadcastRemoteCallback((x) => x.EventToLog("Tunnel Validation: Complete", DateTime.Now)); TunnelValidatorLastPingSuccessful = true; TunnelValidatorLastSuccessfulPingTime = DateTime.Now; } else { HandleFailedTunnelPing(); } } else { WcfServerHelper.BroadcastRemoteCallback((x) => x.EventToLog("Tunnel Validation: Sender Error (1)", DateTime.Now)); HandleFailedTunnelPing(); } stream.Close(); } tcpClient.Close(); } catch (Exception ex) { WcfServerHelper.BroadcastRemoteCallback((x) => x.EventToLog("Tunnel Validation Sender Exception (1): " + ex.Message + " ::: " + ex.StackTrace, DateTime.Now)); HandleFailedTunnelPing(); } finally { ClientHelper.PingClient(); } }); }
protected override void OnStop() { TunnelHelper.ChangeTunnelStatus(TunnelStatuses.Paused, false); Thread.Sleep(300); WcfServerHelper.BroadcastRemoteCallback(x => x.ServerStopping(), true); Thread.Sleep(300); WcfServerHelper.Stop(); }
public static bool StartPlink(ServiceSettings serviceSettings = null, bool testConnection = false) { if (serviceSettings == null) { serviceSettings = SettingsHelper.GetSettings(); } if (string.IsNullOrEmpty(serviceSettings.PlinkExecutable) || !File.Exists(serviceSettings.PlinkExecutable)) { WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.ExecutableNotFound)); return(false); } serviceSettings.EnableVerbose = true; _processInfo = new ProcessStartInfo(); _processInfo.FileName = serviceSettings.PlinkExecutable; _processInfo.Arguments = GetPlinkArguments(serviceSettings); _processInfo.RedirectStandardOutput = true; _processInfo.RedirectStandardError = true; _processInfo.RedirectStandardInput = true; _processInfo.UseShellExecute = false; _processInfo.CreateNoWindow = true; _process = new Process(); _process.StartInfo = _processInfo; _process.Start(); _process.StandardInput.NewLine = Environment.NewLine; if (!testConnection) { _process.Exited += process_Exited; PlinkRunning = true; try { PlinkJobObject plinkJobObject = new PlinkJobObject(); plinkJobObject.AddProcess(_process.Id); } catch (Exception ex) { WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog(ex.Message + " ::: " + ex.StackTrace, DateTime.Now)); return(false); } ClientHelper.PingClient(); } Task.Factory.StartNew(() => ProcessOutputCharacters(_process.StandardError, serviceSettings, testConnection, true)); Task.Factory.StartNew(() => ProcessOutputCharacters(_process.StandardOutput, serviceSettings, testConnection, false)); return(true); }
private static void process_Exited(object sender, EventArgs e) { WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog("Plink Exited", DateTime.Now)); StopPlink(); if (TunnelHelper.CurrentTunnelStatus == TunnelStatuses.Started) { Thread.Sleep(500); WcfServerHelper.BroadcastRemoteCallback(x => x.EventToLog("Plink Restarting", DateTime.Now)); StartPlink(); } }
public void SaveSettings(ServiceSettings serviceSettings, bool restartPlink) { SettingsHelper.SaveSettings(serviceSettings); WcfServerHelper.BroadcastRemoteCallback(x => x.SaveSettingsCallback(SettingsHelper.GetSettings()), true); if (restartPlink && TunnelHelper.CurrentTunnelStatus == TunnelStatuses.Started) { TunnelHelper.ChangeTunnelStatus(TunnelStatuses.Paused, false); Thread.Sleep(400); TunnelHelper.ChangeTunnelStatus(TunnelStatuses.Started, false); } }
private static void HandlePlinkError(PlinkStatus plinkStatus, bool testConnection) { if (!testConnection) { TunnelHelper.CurrentTunnelStatus = TunnelStatuses.Paused; WcfServerHelper.BroadcastRemoteCallback(x => x.TunnelStatusChanged(TunnelStatuses.Paused)); StopPlink(); } else if (!_process.HasExited) { _process.Kill(); } WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(plinkStatus)); }
private static void ProcessLine(string line, bool testConnection) { if (line == null) { return; } WcfServerHelper.BroadcastRemoteCallback(x => x.PlinkTextOutput(line, DateTime.Now)); if (line.Contains("If you do not trust this host, press Return to abandon the")) { _process.StandardInput.Write("y"); _process.StandardInput.Write("\n"); _process.StandardInput.Flush(); } if (testConnection && line.Contains("Access granted")) { if (!_process.HasExited) { _process.Kill(); } WcfServerHelper.BroadcastRemoteCallback(x => x.TestConnectionCallback(PlinkStatus.Success)); } else if (line.Contains("Access denied") || line.Contains("Password authentication failed")) { HandlePlinkError(PlinkStatus.InvalidUserOrPass, testConnection); } else if (line.Contains("Host does not exist")) { HandlePlinkError(PlinkStatus.InvalidHostname, testConnection); } else if (line.Contains("Connection timed out")) { HandlePlinkError(PlinkStatus.TimedOut, testConnection); } }
public static void OpenTunnelPingListener() { if (TunnelValidatorRunning) { CloseTunnelPingListener(); } ServiceSettings serviceSettings = SettingsHelper.GetSettings(); if (TunnelHelper.CurrentTunnelStatus == TunnelStatuses.Started && serviceSettings.EnableTunnelValidation) { TunnelPingHelper.TunnelValidatorLastPingSuccessful = false; _validationListener = new TcpListener(IPAddress.Any, serviceSettings.TunnelValidationRemotePort); Task.Factory.StartNew(() => { TunnelPingHelper.TunnelValidatorRunning = true; _validationListener.Start(); try { while (true) { TcpClient tcpClient; try { tcpClient = _validationListener.AcceptTcpClient(); } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.Interrupted) { TunnelPingHelper.TunnelValidatorRunning = false; break; } else { throw; } } Task.Factory.StartNew(() => { try { NetworkStream clientStream = tcpClient.GetStream(); byte[] message = new byte[32]; string validationString = ""; while (true) { int bytesRead = clientStream.Read(message, 0, 32); if (bytesRead == 0) { break; } ASCIIEncoding encoding = new ASCIIEncoding(); string str = encoding.GetString(message, 0, bytesRead); validationString += str; if (validationString == "-111-") { const string sendString = "-222-"; byte[] sendData = Encoding.ASCII.GetBytes(sendString); clientStream.Write(sendData, 0, sendData.Length); break; } else if (validationString.Length > 5) { break; } } tcpClient.Close(); } catch (Exception ex) { WcfServerHelper.BroadcastRemoteCallback((x) => x.EventToLog("Tunnel Validation Exception (1): " + ex.Message + " ::: " + ex.StackTrace, DateTime.Now)); HandleFailedTunnelPing(); } }); } } catch (Exception ex) { WcfServerHelper.BroadcastRemoteCallback((x) => x.EventToLog("Tunnel Validation Exception (2): " + ex.Message + " ::: " + ex.StackTrace, DateTime.Now)); HandleFailedTunnelPing(); } }, TaskCreationOptions.LongRunning); _pingTunnelTimer = new System.Timers.Timer(); _pingTunnelTimer.Interval = serviceSettings.TunnelValidationPingInterval * 1000; _pingTunnelTimer.AutoReset = true; _pingTunnelTimer.Elapsed += _pingTunnelTimer_Elapsed; Thread.Sleep(1200); SendTunnelPing(); _pingTunnelTimer.Start(); } }