Esempio n. 1
0
        internal ShellStream(Session session, string terminalName, uint columns, uint rows, uint width, uint height, int maxLines, PrivateKeyAgent forwardedPrivateKeyAgent, params KeyValuePair <TerminalModes, uint>[] terminalModeValues)
        {
            this._encoding = new Renci.SshNet.Common.ASCIIEncoding();
            this._session  = session;
            this._incoming = new Queue <byte>();
            this._outgoing = new Queue <byte>();

            this._channel = this._session.CreateChannel <ChannelSession>();
            this._channel.DataReceived += new EventHandler <ChannelDataEventArgs>(Channel_DataReceived);
            this._channel.Closed       += new EventHandler <ChannelEventArgs>(Channel_Closed);
            this._session.Disconnected += new EventHandler <EventArgs>(Session_Disconnected);
            this._session.ErrorOccured += new EventHandler <ExceptionEventArgs>(Session_ErrorOccured);

            this.forwardedPrivateKeyAgent = forwardedPrivateKeyAgent;

            this._channel.Open();
            if (this.forwardedPrivateKeyAgent != null)
            {
                if (this._channel.SendPrivateKeyAgentForwardingRequest())
                {
                    this._session.RegisterMessage("SSH_MSG_CHANNEL_OPEN");
                    this._session.ChannelOpenReceived += OnChannelOpen;
                }
            }
            this._channel.SendPseudoTerminalRequest(terminalName, columns, rows, width, height, terminalModeValues);
            this._channel.SendShellRequest();
        }
Esempio n. 2
0
        internal ShellStream(Session session, string terminalName, uint columns, uint rows, uint width, uint height, int maxLines, PrivateKeyAgent forwardedPrivateKeyAgent, params KeyValuePair<TerminalModes, uint>[] terminalModeValues)
        {
            this._encoding = new Renci.SshNet.Common.ASCIIEncoding();
            this._session = session;
            this._incoming = new Queue<byte>();
            this._outgoing = new Queue<byte>();

            this._channel = this._session.CreateChannel<ChannelSession>();
            this._channel.DataReceived += new EventHandler<ChannelDataEventArgs>(Channel_DataReceived);
            this._channel.Closed += new EventHandler<ChannelEventArgs>(Channel_Closed);
            this._session.Disconnected += new EventHandler<EventArgs>(Session_Disconnected);
            this._session.ErrorOccured += new EventHandler<ExceptionEventArgs>(Session_ErrorOccured);

            this.forwardedPrivateKeyAgent = forwardedPrivateKeyAgent;

            this._channel.Open();
            if (this.forwardedPrivateKeyAgent != null)
            {
                if (this._channel.SendPrivateKeyAgentForwardingRequest())
                {
                    this._session.RegisterMessage("SSH_MSG_CHANNEL_OPEN");
                    this._session.ChannelOpenReceived += OnChannelOpen;
                }
            }
            this._channel.SendPseudoTerminalRequest(terminalName, columns, rows, width, height, terminalModeValues);
            this._channel.SendShellRequest();
        }
Esempio n. 3
0
        /// <summary>
        /// Establishes the connection to the server, using the specified <paramref name="terminal"/> for connection initialization (authentication, etc.).
        /// </summary>
        /// <param name="terminal">The terminal to use for connection initialization.</param>
        /// <returns>A value indicating whether the connection was successfully established.</returns>
        /// <exception cref="ObjectDisposedException">The connection object is already disposed.</exception>
        /// <exception cref="InvalidOperationException">The connection object is currently connected.</exception>
        public async Task<bool> ConnectAsync(IConnectionInitializingTerminal terminal)
        {
            this.CheckDisposed();
            this.MustBeConnected(false);

            Lazy<string> username = new Lazy<string>(() =>
            {
                if (string.IsNullOrEmpty(this.connectionData.Username))
                {
                    return terminal.ReadLineAsync("Username: "******"Username: "******"Password: "******"Password expired for user " + e.Username);
                                do
                                {
                                    var readNewPassword1Task = terminal.ReadLineAsync("New password: "******"Repeat new password: "******"Performing keyboard-interactive authentication.");
                                }

                                if (!string.IsNullOrEmpty(e.Instruction))
                                {
                                    terminal.WriteLine(e.Instruction);
                                }

                                foreach (var prompt in e.Prompts)
                                {
                                    var readLineTask = terminal.ReadLineAsync(prompt.Request, echo: prompt.IsEchoed);
                                    readLineTask.Wait();
                                    prompt.Response = readLineTask.Result;
                                }
                            };
                            connectionInfo = keyboardInteractiveConnectionInfo;
                            break;
                        case Model.AuthenticationType.PrivateKey:
                            if (this.privateKeyData == null)
                            {
                                throw new Exception("Private Key '" + connectionData.PrivateKeyName + "' not found. Please correct the authentication details of the connection.");
                            }

                            PrivateKeyFile privateKey;

                            try
                            {
                                using (var privateKeyStream = new MemoryStream(privateKeyData.Data))
                                {
                                    privateKey = new PrivateKeyFile(privateKeyStream);
                                }
                            }
                            catch (SshPassPhraseNullOrEmptyException)
                            {
                                privateKey = null;
                            }

                            // In the normal PrivateKey authentication there is only a connection-local PrivateKeyAgent.
                            var localPprivateKeyAgent = new Lazy<PrivateKeyAgent>(() =>
                            {
                                terminal.WriteLine("Performing authentication with Private Key '" + connectionData.PrivateKeyName + "'.");

                                if (privateKey == null)
                                {
                                    string privateKeyPassword = terminal.ReadLineAsync("Private Key password: "******"Wrong Private Key password, please try again.", ex);
                                        }
                                    }
                                }

                                var pka = new PrivateKeyAgent();
                                pka.AddSsh2(privateKey.HostKey, connectionData.PrivateKeyName);
                                return pka;
                            });

                            var privateKeyConnectionInfo = new PrivateKeyConnectionInfo(this.connectionData.Host, this.connectionData.Port, username, localPprivateKeyAgent);
                            connectionInfo = privateKeyConnectionInfo;

                            break;
                        case AuthenticationType.PrivateKeyAgent:
                            if (PrivateKeyAgentManager.PrivateKeyAgent.ListSsh2().Count == 0)
                            {
                                throw new SshAuthenticationException("The private key agent doesn't contain any private keys.");
                            }

                            var globalPrivateKeyAgent = new Lazy<PrivateKeyAgent>(() =>
                            {
                                var pka = PrivateKeyAgentManager.PrivateKeyAgent;
                                terminal.WriteLine("Performing private key agent authentication.");
                                return pka;
                            });

                            var privateKeyAgentConnectionInfo = new PrivateKeyConnectionInfo(this.connectionData.Host, this.connectionData.Port, username, globalPrivateKeyAgent);
                            connectionInfo = privateKeyAgentConnectionInfo;
                            if (connectionData.PrivateKeyAgentForwarding == true)
                            {
                                forwardedPrivateKeyAgent = globalPrivateKeyAgent;
                                terminal.WriteLine("Agent forwarding is enabled.");
                            }

                            break;
                        default:
                            throw new NotImplementedException("Authentication method '" + this.connectionData.Authentication + "' not implemented.");
                    }

                    connectionInfo.AuthenticationBanner += (sender, e) =>
                    {
                        terminal.WriteLine(e.BannerMessage.Replace("\n", "\r\n"));
                    };

                    this.client = new SshClient(connectionInfo);
                    this.client.HostKeyReceived += (s, e) =>
                    {
                        string fingerprint = string.Join(":", e.FingerPrint.Select(b => b.ToString("x2")));

                        bool trustHostKey = true;
                        bool storeHostKey = false;

                        string newHostKey = string.Join(null, e.HostKey.Select(b => b.ToString("x2")));
                        if (oldHostKey == null)
                        {
                            terminal.WriteLine("Remote Terminal has not yet cached a host key for this server.");
                            terminal.WriteLine("Host key's fingerprint: " + fingerprint);
                            terminal.WriteLine("Please make sure the fingerprint matches the server's actual host key.");
                            trustHostKey = QueryYesNo(terminal, "Do you want to continue connecting to the host?");
                            if (trustHostKey)
                            {
                                storeHostKey = QueryYesNo(terminal, "Do you want to store this host key in the cache?");
                            }
                        }
                        else if (oldHostKey != newHostKey)
                        {
                            terminal.WriteLine("POSSIBLE SECURITY BREACH DETECTED!");
                            terminal.WriteLine("Remote Terminal has cached another host key for this server.");
                            terminal.WriteLine("This could mean one of two things:");
                            terminal.WriteLine(" * the server's host key was changed by an administrator");
                            terminal.WriteLine(" * another computer is trying to intercept your connection");
                            terminal.WriteLine("Host key's new fingerprint: " + fingerprint);
                            trustHostKey = QueryYesNo(terminal, "Do you want to continue connecting to the host?");
                            if (trustHostKey)
                            {
                                storeHostKey = QueryYesNo(terminal, "Do you want to update the cache with the new host key?");
                            }
                        }

                        e.CanTrust = trustHostKey;
                        if (trustHostKey)
                        {
                            oldHostKey = newHostKey;
                        }

                        if (storeHostKey)
                        {
                            HostKeysDataSource.AddOrUpdate(this.connectionData.Host, this.connectionData.Port, newHostKey);
                        }
                    };

                    this.client.ConnectionInfo.Timeout = new TimeSpan(0, 15, 0);
                    await Task.Run(() => { this.client.Connect(); });
                    this.client.ConnectionInfo.Timeout = new TimeSpan(0, 1, 0);

                    var terminalModes = new Dictionary<TerminalModes, uint>();
                    terminalModes[TerminalModes.TTY_OP_ISPEED] = 0x00009600;
                    terminalModes[TerminalModes.TTY_OP_OSPEED] = 0x00009600;
                    this.stream = this.client.CreateShellStream(terminal.TerminalName, (uint)terminal.Columns, (uint)terminal.Rows, 0, 0, 1024, forwardedPrivateKeyAgent.Value, terminalModes.ToArray());

                    this.reader = new StreamReader(this.stream);
                    this.writer = new StreamWriter(this.stream);
                    this.writer.AutoFlush = true;
                    return true;
                }
                catch (SshConnectionException ex)
                {
                    terminal.WriteLine(ex.Message);
                    retry = false;
                }
                catch (SshAuthenticationException ex)
                {
                    terminal.WriteLine(ex.Message);
                    if (connectionData.Authentication == AuthenticationType.PrivateKeyAgent)
                    {
                        terminal.WriteLine("Please load the necessary private key(s) into the private key agent.");
                        retry = false;
                    }
                    else
                    {
                        retry = true;
                    }
                }
                catch (Exception ex)
                {
                    terminal.WriteLine(ex.Message);
                    retry = false;
                }

                if (!retry || numRetries++ > 5)
                {
                    return false;
                }
            }
            while (true);
        }
Esempio n. 4
0
        /// <summary>
        /// Creates the shell stream.
        /// </summary>
        /// <param name="terminalName">Name of the terminal.</param>
        /// <param name="columns">The columns.</param>
        /// <param name="rows">The rows.</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="bufferSize">Size of the buffer.</param>
        /// <param name="terminalModeValues">The terminal mode values.</param>
        /// <returns></returns>
        public ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize, PrivateKeyAgent forwardedPrivateKeyAgent, params KeyValuePair <TerminalModes, uint>[] terminalModeValues)
        {
            //  Ensure that connection is established.
            this.EnsureConnection();

            return(new ShellStream(this.Session, terminalName, columns, rows, width, height, bufferSize, forwardedPrivateKeyAgent, terminalModeValues));
        }
Esempio n. 5
0
        /// <summary>
        /// Creates the shell stream.
        /// </summary>
        /// <param name="terminalName">Name of the terminal.</param>
        /// <param name="columns">The columns.</param>
        /// <param name="rows">The rows.</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="bufferSize">Size of the buffer.</param>
        /// <param name="terminalModeValues">The terminal mode values.</param>
        /// <returns></returns>
        public ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize, PrivateKeyAgent forwardedPrivateKeyAgent, params KeyValuePair<TerminalModes, uint>[] terminalModeValues)
        {
            //  Ensure that connection is established.
            this.EnsureConnection();

            return new ShellStream(this.Session, terminalName, columns, rows, width, height, bufferSize, forwardedPrivateKeyAgent, terminalModeValues);
        }