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);
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        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;
        }
예제 #5
0
        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();
                }
            });
        }
예제 #6
0
        protected override void OnStop()
        {
            TunnelHelper.ChangeTunnelStatus(TunnelStatuses.Paused, false);
            Thread.Sleep(300);

            WcfServerHelper.BroadcastRemoteCallback(x => x.ServerStopping(), true);
            Thread.Sleep(300);

            WcfServerHelper.Stop();
        }
예제 #7
0
        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);
        }
예제 #8
0
        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();
            }
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
        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));
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
        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();
            }
        }