Example #1
0
        public static string PuttyArguments(HostInfo host, PuttyProfile profile, AuthenticationType authType)
        {
            // example: -ssh -load _stm_preset_ username@domainName -P 22 -pw password -D 5000 -L 44333:username.dyndns.org:44333

            string profileArg = "";

            if (profile != null)
            {
                profileArg = @" -load " + profile.Name;
            }

            var startShellOption = "";

            if (string.IsNullOrWhiteSpace(host.RemoteCommand))
            {
                startShellOption = " -N";
            }

            string args;

            switch (authType)
            {
            case AuthenticationType.None:
                args = String.Format(@"-ssh{0} {1}@{2} -P {3} -v{4}", profileArg, host.Username, host.Hostname,
                                     host.Port, startShellOption);
                Logger.Log.DebugFormat(@"plink.exe {0}", args);
                break;

            case AuthenticationType.Password:
                args = String.Format(@"-ssh{0} {1}@{2} -P {3} -pw {4} -v{5}", profileArg, host.Username, host.Hostname,
                                     host.Port, host.Password, startShellOption);
                Logger.Log.DebugFormat(@"plink.exe -ssh{0} {1}@{2} -P {3} -pw ******** -v -N", profileArg, host.Username,
                                       host.Hostname, host.Port);
                break;

            case AuthenticationType.PrivateKey:
                args = String.Format(@"-ssh{0} {1}@{2} -P {3} -i {4} -v{5}", profileArg, host.Username, host.Hostname,
                                     host.Port, PrivateKeysStorage.CreatePrivateKey(host).Filename, startShellOption);
                Logger.Log.DebugFormat(@"plink.exe {0}", args);
                break;

            default:
                throw new ArgumentOutOfRangeException("authType");
            }
            var sb = new StringBuilder(args);

            foreach (var tunnelArg in host.Tunnels.Select(tunnelArguments))
            {
                sb.Append(tunnelArg);
            }

            args = sb.ToString();
            return(args);
        }
Example #2
0
        private static string psftpArguments(HostInfo host)
        {
            string args;

            switch (host.AuthType)
            {
            case AuthenticationType.Password:
                args = String.Format(@"{0}@{1} -P {2} -pw {3} -batch", host.Username, host.Hostname, host.Port,
                                     host.Password);
                break;

            case AuthenticationType.PrivateKey:
                args = String.Format(@"{0}@{1} -P {2} -i {3} -batch", host.Username, host.Hostname, host.Port,
                                     PrivateKeysStorage.CreatePrivateKey(host).Filename);
                break;

            default:
                throw new ArgumentOutOfRangeException("authType");
            }
            return(args);
        }
Example #3
0
        private void errorDataHandler(object o, DataReceivedEventArgs args)
        {
            if (args.Data == null)
            {
                return;
            }
            ThreadContext.Properties[@"Host"] = Host; // Set up context for working thread
            Logger.Log.Debug(args.Data);
            // LOCAL tunnels error
            var m = Regex.Match(args.Data, @"Local port (?<srcPort>\d+) forwarding to (?<dstHost>[^:]+):(?<dstPort>\d+) failed: (?<errorString>.*)", RegexOptions.IgnoreCase);

            if (m.Success)
            {
                var srcPort     = m.Groups["srcPort"].Value;
                var dstHost     = m.Groups["dstHost"].Value;
                var dstPort     = m.Groups["dstPort"].Value;
                var errorString = m.Groups["errorString"].Value;
                var tunnel      = Host.Tunnels.FirstOrDefault(
                    t => t.LocalPort == srcPort && t.RemoteHostname == dstHost && t.RemotePort == dstPort && t.Type == TunnelType.Local);
                if (tunnel != null)
                {
                    lock (_forwardingResultsLock)
                    {
                        _forwardingResults[tunnel] = ForwardingResult.CreateFailed(errorString);
                    }

                    Logger.Log.WarnFormat("[{0}] [{1}] {2}", Host.Name, tunnel.SimpleString, errorString);
                }
            }
            // DYNAMIC tunnels error
            m = Regex.Match(args.Data, @"Local port (?<srcPort>\d+) SOCKS dynamic forwarding failed: (?<errorString>.*)", RegexOptions.IgnoreCase);
            if (m.Success)
            {
                var srcPort     = m.Groups["srcPort"].Value;
                var errorString = m.Groups["errorString"].Value;
                var tunnel      = Host.Tunnels.FirstOrDefault(
                    t => t.LocalPort == srcPort && t.Type == TunnelType.Dynamic);
                if (tunnel != null)
                {
                    lock (_forwardingResultsLock)
                    {
                        _forwardingResults[tunnel] = ForwardingResult.CreateFailed(errorString);
                    }
                    Logger.Log.WarnFormat("[{0}] [{1}] {2}", Host.Name, tunnel.SimpleString, errorString);
                }
            }
            // Accept certificate
            if (args.Data.Contains(@"The server's host key is not cached in the registry."))
            {
                writeStdIn(@"y");
            }
            // Unable to open connection:
            if (args.Data.Contains(@"Unable to open connection:"))
            {
                _multilineError.Append(@"Unable to open connection: ");
                return;
            }
            // Access denied error
            if (args.Data.Contains(@"Access denied"))
            {
                // Неверный пароль (Доступ запрещен)
                LastStartError = @"Access Denied";
                stop();
            }
            // Access granted
            if (args.Data.Contains(@"Access granted"))
            {
                // Доступ открыт, можно удалить ключ
                PrivateKeysStorage.RemovePrivateKey(Host);
                Logger.Log.Debug(string.Format("Access granted called: {0}", Host));

                // Make delay for a couple of seconds and set status to 'Started' if a shell is not supposed to be started
                if (string.IsNullOrWhiteSpace(Host.RemoteCommand))
                {
                    _deferredCallTimer = new Timer(
                        delegate
                    {
                        bool forwardingFailed;
                        lock (_forwardingResultsLock)
                        {
                            forwardingFailed = _forwardingResults.Any(p => !p.Value.Success);
                        }

                        ThreadContext.Properties[@"Host"] = Host;
                        Logger.Log.Debug(string.Format("Delegate called: {0}", Host));
                        Status = forwardingFailed
                                         ? ELinkStatus.StartedWithWarnings
                                         : ELinkStatus.Started;
                        ThreadContext.Properties[@"Host"] = null;
                    },
                        null,
                        1500,
                        Timeout.Infinite);
                }
            }

            // Fatal errors
            m = Regex.Match(args.Data, @"^FATAL ERROR:\s*(?<msg>.*)$");
            if (m.Success)
            {
                LastStartError = m.Groups["msg"].Value;
            }

            // connection establishing
            if (args.Data.Contains(ShellStartedMessage))
            {
                bool forwardingFails;
                lock (_forwardingResultsLock)
                {
                    forwardingFails = _forwardingResults.Any(p => !p.Value.Success);
                }

                Status = forwardingFails ? ELinkStatus.StartedWithWarnings : ELinkStatus.Started;

                // Start a command to be executed after connection establishment
                if (!string.IsNullOrWhiteSpace(Host.RemoteCommand))
                {
                    _deferredCallTimer = new Timer(
                        delegate
                    {
                        ThreadContext.Properties[@"Host"] = Host;
                        writeLineStdIn(Host.RemoteCommand);
                        ThreadContext.Properties[@"Host"] = null;
                    },
                        null,
                        1000,
                        Timeout.Infinite);
                }
            }

            // multiline error?
            if (_multilineError.Length > 0)
            {
                _multilineError.Append(args.Data);
                LastStartError = _multilineError.ToString();
                _multilineError.Clear();
                stop();
            }

            ThreadContext.Properties[@"Host"] = null;
        }
Example #4
0
        /// <summary>
        /// Start attemt to establish link once.
        /// </summary>
        /// <returns>Link was successfully started.</returns>
        private bool startOnce()
        {
            // fill results dic
            lock (_forwardingResultsLock)
            {
                _forwardingResults = Host.Tunnels.ToDictionary(t => t, t => ForwardingResult.CreateSuccess());
            }

            // Процесс
            _process = new Process
            {
                StartInfo =
                {
                    FileName               = ConsoleTools.PLinkLocation,
                    CreateNoWindow         = true,
                    UseShellExecute        = false,
                    RedirectStandardError  = true,
                    RedirectStandardOutput = true,
                    RedirectStandardInput  = true,
                    Arguments              = ConsoleTools.PuttyArguments(Host, _profile, Host.AuthType)
                }
            };

            _process.ErrorDataReceived += errorDataHandler;
            _process.Start();
            _process.BeginErrorReadLine();

            _process.StandardInput.AutoFlush = true;

            var  buffer                   = new StringBuilder();
            bool passwordProvided         = false;
            bool passphraseForKeyProvided = false;

            while (!_process.HasExited)
            {
                while (_process.StandardOutput.Peek() >= 0)
                {
                    char c = (char)_process.StandardOutput.Read();
                    buffer.Append(c);
                }

                _process.StandardOutput.DiscardBufferedData();
                string data = buffer.ToString().ToLower();

                buffer.Clear();

                if (data.Contains(@"login as:"))
                {
                    // invalid username provided
                    stop();
                    // _process.StandardInput.WriteLine(username);
                    LastStartError = Resources.PuttyLink_Error_InvalidUsername;
                }
                else if (data.Contains(@"password:"******"passphrase for key") && !passphraseForKeyProvided)
                {
                    writeLineStdIn(Host.Password);
                    passphraseForKeyProvided = true;
                }
                else
                {
                    foreach (var line in data.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        Logger.Log.Debug(line);
                    }
                }
            }

            PrivateKeysStorage.RemovePrivateKey(Host);
            return(Status == ELinkStatus.Started || Status == ELinkStatus.StartedWithWarnings);
        }
Example #5
0
        /// <summary>
        /// Start attemt to establish link once.
        /// </summary>
        /// <returns>Link was successfully started.</returns>
        private bool startOnce(TimeSpan?connectionTimeout)
        {
            // fill results dic
            lock (_forwardingResultsLock)
            {
                _forwardingResults = Host.Tunnels.ToDictionary(t => t, t => ForwardingResult.CreateSuccess());
            }

            // Процесс
            _process = new Process
            {
                StartInfo =
                {
                    FileName               = ConsoleTools.PLinkLocation,
                    CreateNoWindow         = true,
                    UseShellExecute        = false,
                    RedirectStandardError  = true,
                    RedirectStandardOutput = true,
                    RedirectStandardInput  = true,
                    Arguments              = ConsoleTools.PuttyArguments(Host, _profile, Host.AuthType, true)
                }
            };

            _process.ErrorDataReceived += errorDataHandler;
            _process.Start();
            _process.BeginErrorReadLine();

            _process.StandardInput.AutoFlush = true;
            var p = _process;
            var processAutoKillTimer = connectionTimeout == null
                                ? null
                                : new Timer(delegate
            {
                ThreadContext.Properties[@"Host"] = Host;
                var connectionStarted             = Status == ELinkStatus.Started || Status == ELinkStatus.StartedWithWarnings;
                if (!connectionStarted && p == _process)
                {
                    try { p.Kill(); }
                    catch { /**/ }
                    Logger.Log.WarnFormat("[{0}] {1}", Host.Name, $"Connection timeout ({connectionTimeout})...");
                }

                ThreadContext.Properties[@"Host"] = null;
            }, null, (long)connectionTimeout.Value.TotalMilliseconds, Timeout.Infinite);

            var  buffer                   = new StringBuilder();
            bool passwordProvided         = false;
            bool passphraseForKeyProvided = false;

            while (!_process.HasExited)
            {
                while (_process.StandardOutput.Peek() >= 0)
                {
                    char c = (char)_process.StandardOutput.Read();
                    buffer.Append(c);
                }

                _process.StandardOutput.DiscardBufferedData();
                string data = buffer.ToString().ToLower();

                buffer.Clear();

                if (data.Contains(@"login as:"))
                {
                    // invalid username provided
                    stop();
                    // _process.StandardInput.WriteLine(username);
                    LastStartError = Resources.PuttyLink_Error_InvalidUsername;
                }
                else if (data.Contains(@"password:"******"passphrase for key") && !passphraseForKeyProvided)
                {
                    writeLineStdIn(Host.Password);
                    passphraseForKeyProvided = true;
                }
                else
                {
                    foreach (var line in data.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        Logger.Log.Debug(line);
                    }
                }
            }

            processAutoKillTimer?.Dispose();
            PrivateKeysStorage.RemovePrivateKey(Host);
            return(Status == ELinkStatus.Started || Status == ELinkStatus.StartedWithWarnings);
        }
Example #6
0
        public static string PuttyArguments(HostInfo host, PuttyProfile profile, AuthenticationType authType, bool addTunnels)
        {
            // example: -ssh -load _stm_preset_ username@domainName -P 22 -pw password -D 5000 -L 44333:username.dyndns.org:44333

            string profileArg = "";

            if (profile != null)
            {
                profileArg = @" -load " + profile.Name;
            }

            var startShellOption = "";

            if (string.IsNullOrWhiteSpace(host.RemoteCommand) && addTunnels)
            {
                startShellOption = " -N";
            }

            string args;

            switch (authType)
            {
            case AuthenticationType.None:
                args = String.Format(@"-ssh{0} {1}@{2} -P {3} -v{4}", profileArg, host.Username, host.CurrentHostAndPort.Hostname,
                                     host.CurrentHostAndPort.Port, startShellOption);
                //Logger.Log.DebugFormat(@"plink.exe {0}", args);
                break;

            case AuthenticationType.Password:
                args = String.Format(@"-ssh{0} {1}@{2} -P {3} -pw {4} -v{5}", profileArg, host.Username, host.CurrentHostAndPort.Hostname,
                                     host.CurrentHostAndPort.Port, host.Password, startShellOption);
                //Logger.Log.DebugFormat(@"plink.exe -ssh{0} {1}@{2} -P {3} -pw ******** -v -N", profileArg, host.Username,host.Hostname, host.Port);
                break;

            case AuthenticationType.PrivateKey:
                args = String.Format(@"-ssh{0} {1}@{2} -P {3} -i ""{4}"" -v{5}", profileArg, host.Username, host.CurrentHostAndPort.Hostname,
                                     host.CurrentHostAndPort.Port, PrivateKeysStorage.CreatePrivateKey(host).Filename, startShellOption);
                //Logger.Log.DebugFormat(@"plink.exe {0}", args);
                break;

            default:
                throw new ArgumentOutOfRangeException("authType");
            }

            if (addTunnels)
            {
                var sb = new StringBuilder(args);
                foreach (var tunnelArg in host.Tunnels.Select(tunnelArguments))
                {
                    sb.Append(tunnelArg);
                }

                args = sb.ToString();
            }

            Logger.Log.DebugFormat(@"plink.exe {0}", args.Replace("-pw " + host.Password + " ", "-pw ********* "));

            if (addTunnels && host.Tunnels.Any())
            {
                var ports     = host.Tunnels.Select(x => x.LocalPort).ToList();
                var ipGP      = IPGlobalProperties.GetIPGlobalProperties();
                var endpoints = ipGP.GetActiveTcpListeners();
                var portUsed  = endpoints.Select(x => x.Port.ToString()).Distinct().Where(x => ports.Contains(x)).ToList();
                if (portUsed.Any())
                {
                    var portsDetail = NetStatPortsAndProcessNames.GetNetStatPorts().ToLookup(x => x.port_number);
                    if (portUsed.Count == 1)
                    {
                        throw new Exception("La porta " + portUsed[0] + " è già in uso da '" + portsDetail[portUsed[0]].Select(p => p.process_name).FirstOrDefault() + "'.");
                    }
                    portUsed = portUsed.Select(x =>
                                               x + " (" + portsDetail[x].Select(p => p.process_name).FirstOrDefault() + ")").ToList();
                    throw new Exception("Le seguenti porto sono già in uso: " + string.Join(", ", portUsed));
                }
            }

            return(args);
        }