Implements Session SSH channel.
Inheritance: Channel
Exemple #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();
        }
        private void Arrange()
        {
            var random = new Random();
            _localChannelNumber = (uint)random.Next(0, int.MaxValue);
            _localWindowSize = (uint)random.Next(0, int.MaxValue);
            _localPacketSize = (uint)random.Next(0, int.MaxValue);
            _remoteChannelNumber = (uint)random.Next(0, int.MaxValue);
            _remoteWindowSize = (uint)random.Next(0, int.MaxValue);
            _remotePacketSize = (uint)random.Next(0, int.MaxValue);
            _channelClosedRegister = new List<ChannelEventArgs>();
            _channelExceptionRegister = new List<ExceptionEventArgs>();
            _initialSessionSemaphoreCount = random.Next(10, 20);
            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);

            _sessionMock = new Mock<ISession>(MockBehavior.Strict);
            _connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);

            _sequence = new MockSequence();
            _sessionMock.InSequence(_sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
            _connectionInfoMock.InSequence(_sequence).Setup(p => p.RetryAttempts).Returns(1);
            _sessionMock.Setup(p => p.SessionSemaphore).Returns(_sessionSemaphore);
            _sessionMock.InSequence(_sequence)
                .Setup(
                    p =>
                        p.SendMessage(
                            It.Is<ChannelOpenMessage>(
                                m =>
                                    m.LocalChannelNumber == _localChannelNumber &&
                                    m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize &&
                                    m.Info is SessionChannelOpenInfo)));
            _sessionMock.InSequence(_sequence)
                .Setup(p => p.WaitOnHandle(It.IsNotNull<WaitHandle>()))
                .Callback<WaitHandle>(
                    w =>
                    {
                        _sessionMock.Raise(
                            s => s.ChannelOpenConfirmationReceived += null,
                            new MessageEventArgs<ChannelOpenConfirmationMessage>(
                                new ChannelOpenConfirmationMessage(
                                    _localChannelNumber,
                                    _remoteWindowSize,
                                    _remotePacketSize,
                                    _remoteChannelNumber)));
                        w.WaitOne();
                    });
            _sessionMock.Setup(p => p.IsConnected).Returns(false);

            _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
            _channel.Closed += (sender, args) => _channelClosedRegister.Add(args);
            _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args);
            _channel.Open();

            _sessionMock.Raise(
                p => p.ChannelEofReceived += null,
                new MessageEventArgs<ChannelEofMessage>(new ChannelEofMessage(_localChannelNumber)));
            _sessionMock.Raise(
                p => p.ChannelCloseReceived += null,
                new MessageEventArgs<ChannelCloseMessage>(new ChannelCloseMessage(_localChannelNumber)));
        }
        /// <summary>
        /// Connects subsystem on SSH channel.
        /// </summary>
        public void Connect()
        {
            this._channel = this._session.CreateClientChannel<ChannelSession>();

            this._session.ErrorOccured += Session_ErrorOccured;
            this._session.Disconnected += Session_Disconnected;
            this._channel.DataReceived += Channel_DataReceived;
            this._channel.Closed += Channel_Closed;
            this._channel.Open();
            this._channel.SendSubsystemRequest(_subsystemName);
            this.OnChannelOpen();
        }
        internal ShellStream(Session session, string terminalName, uint columns, uint rows, uint width, uint height, int maxLines, IDictionary<TerminalModes, uint> terminalModeValues)
        {
            this._encoding = session.ConnectionInfo.Encoding;
            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._channel.Open();
            this._channel.SendPseudoTerminalRequest(terminalName, columns, rows, width, height, terminalModeValues);
            this._channel.SendShellRequest();
        }
        private void Arrange()
        {
            var random = new Random();
            _localChannelNumber = (uint)random.Next(0, int.MaxValue);
            _localWindowSize = (uint)random.Next(2000, 3000);
            _localPacketSize = (uint)random.Next(1000, 2000);
            _initialSessionSemaphoreCount = random.Next(10, 20);
            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
            _channelClosedRegister = new List<ChannelEventArgs>();
            _channelExceptionRegister = new List<ExceptionEventArgs>();
            _waitOnConfirmationException = new SystemException();

            _sessionMock = new Mock<ISession>(MockBehavior.Strict);
            _connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);

            var sequence = new MockSequence();
            _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
            _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(2);
            _sessionMock.Setup(p => p.SessionSemaphore).Returns(_sessionSemaphore);
            _sessionMock.InSequence(sequence)
                .Setup(
                    p =>
                        p.SendMessage(
                            It.Is<ChannelOpenMessage>(
                                m =>
                                    m.LocalChannelNumber == _localChannelNumber &&
                                    m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize &&
                                    m.Info is SessionChannelOpenInfo)));
            _sessionMock.InSequence(sequence)
                .Setup(p => p.WaitOnHandle(It.IsNotNull<WaitHandle>()))
                .Throws(_waitOnConfirmationException);

            _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
            _channel.Closed += (sender, args) => _channelClosedRegister.Add(args);
            _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args);
        }
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (this._channel != null)
            {
                this._channel.Dispose();
                this._channel = null;
            }

            if (this._dataReceived != null)
            {
                this._dataReceived.Dispose();
                this._dataReceived = null;
            }

            if (this._session != null)
            {
                this._session.Disconnected -= new EventHandler<EventArgs>(Session_Disconnected);
                this._session.ErrorOccured -= new EventHandler<ExceptionEventArgs>(Session_ErrorOccured);
            }
        }
Exemple #7
0
partial         void SendData(ChannelSession channel, string command)
        {
            channel.SendData(System.Text.Encoding.Default.GetBytes(command));
        }
Exemple #8
0
 private void InternalUpload(ChannelSession channel, Stream input, FileInfo fileInfo, string filename)
 {
     this.InternalSetTimestamp(channel, input, fileInfo.LastWriteTimeUtc, fileInfo.LastAccessTimeUtc);
     using (var source = fileInfo.OpenRead())
     {
         this.InternalUpload(channel, input, source, filename);
     }
 }
Exemple #9
0
 private void SendData(ChannelSession channel, byte[] buffer)
 {
     channel.SendData(buffer);
 }
Exemple #10
0
partial         void SendData(ChannelSession channel, string command);
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged ResourceMessages.</param>
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this._isDisposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged ResourceMessages.
                if (disposing)
                {

                    this._session.Disconnected -= Session_Disconnected;
                    this._session.ErrorOccured -= Session_ErrorOccured;

                    // Dispose managed ResourceMessages.
                    if (this.OutputStream != null)
                    {
                        this.OutputStream.Dispose();
                        this.OutputStream = null;
                    }

                    // Dispose managed ResourceMessages.
                    if (this.ExtendedOutputStream != null)
                    {
                        this.ExtendedOutputStream.Dispose();
                        this.ExtendedOutputStream = null;
                    }

                    // Dispose managed ResourceMessages.
                    if (this._sessionErrorOccuredWaitHandle != null)
                    {
                        this._sessionErrorOccuredWaitHandle.Dispose();
                        this._sessionErrorOccuredWaitHandle = null;
                    }

                    // Dispose managed ResourceMessages.
                    if (this._channel != null)
                    {
                        this._channel.DataReceived -= Channel_DataReceived;
                        this._channel.ExtendedDataReceived -= Channel_ExtendedDataReceived;
                        this._channel.RequestReceived -= Channel_RequestReceived;
                        this._channel.Closed -= Channel_Closed;

                        this._channel.Dispose();
                        this._channel = null;
                    }
                }

                // Note disposing has been done.
                this._isDisposed = true;
            }
        }
        /// <summary>
        /// Waits for the pending asynchronous command execution to complete.
        /// </summary>
        /// <param name="asyncResult">The reference to the pending asynchronous request to finish.</param>
        /// <returns></returns>
        public string EndExecute(IAsyncResult asyncResult)
        {
            if (this._asyncResult == asyncResult && this._asyncResult != null)
            {
                lock (this._endExecuteLock)
                {
                    if (this._asyncResult != null)
                    {
                        //  Make sure that operation completed if not wait for it to finish
                        this.WaitHandle(this._asyncResult.AsyncWaitHandle);

                        this._channel.Close();

                        this._channel = null;

                        this._asyncResult = null;

                        return this.Result;
                    }
                }
            }

            throw new ArgumentException("Either the IAsyncResult object did not come from the corresponding async method on this type, or EndExecute was called multiple times with the same IAsyncResult.");
        }
Exemple #13
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (this._channel != null)
            {
                this._channel.Dispose();
                this._channel = null;
            }

            if (this._dataReceived != null)
            {
                this._dataReceived.Dispose();
                this._dataReceived = null;
            }

            if (this._session != null)
            {
                this._session.Disconnected -= Session_Disconnected;
                this._session.ErrorOccured -= Session_ErrorOccured;
            }
        }
Exemple #14
0
        /// <summary>
        /// Starts this shell.
        /// </summary>
        /// <exception cref="SshException">Shell is started.</exception>
        public void Start()
        {
            if (this.IsStarted)
            {
                throw new SshException("Shell is started.");
            }

            if (this.Starting != null)
            {
                this.Starting(this, new EventArgs());
            }

            this._channel = this._session.CreateChannel<ChannelSession>();
            this._channel.DataReceived += Channel_DataReceived;
            this._channel.ExtendedDataReceived += Channel_ExtendedDataReceived;
            this._channel.Closed += Channel_Closed;
            this._session.Disconnected += Session_Disconnected;
            this._session.ErrorOccured += Session_ErrorOccured;

            this._channel.Open();
            //  TODO:   Terminal mode is ignored as this functionality will be obsolete
            this._channel.SendPseudoTerminalRequest(this._terminalName, this._columns, this._rows, this._width, this._height);
            this._channel.SendShellRequest();

            this._channelClosedWaitHandle = new AutoResetEvent(false);

            //  Start input stream listener
            this._dataReaderTaskCompleted = new ManualResetEvent(false);
            this.ExecuteThread(() =>
            {
                try
                {
                    var buffer = new byte[this._bufferSize];

                    while (this._channel.IsOpen)
                    {
                        var asyncResult = this._input.ReadAsync(buffer, 0, buffer.Length);

                        bool waitingFinished = true;
                        while (!waitingFinished)
                        {
                            // Is it possible to WaitAny() on a Task and a WaitHandle?
                            //EventWaitHandle.WaitAny(new WaitHandle[] { asyncResult.AsyncWaitHandle, this._channelClosedWaitHandle });
                            // this is a workaround:
                            waitingFinished = asyncResult.Wait(100);
                            if (!waitingFinished)
                            {
                                waitingFinished = this._channelClosedWaitHandle.WaitOne(100);
                            }
                        }

                        if (asyncResult.IsCompleted)
                        {
                            //  If input stream is closed and disposed already dont finish reading the stream
                            if (this._input == null)
                                return;

                            var read = asyncResult.Result;
                            if (read > 0)
                            {
                                this._channel.SendData(buffer.Take(read).ToArray());
                            }

                            continue;
                        }
                        else
                            break;
                    }
                }
                catch (Exception exp)
                {
                    this.RaiseError(new ExceptionEventArgs(exp));
                }
                finally
                {
                    this._dataReaderTaskCompleted.Set();
                }
            });

            this.IsStarted = true;

            if (this.Started != null)
            {
                this.Started(this, new EventArgs());
            }
        }
Exemple #15
0
        /// <summary>
        /// Releases the unmanaged resources used by the <see cref="T:System.IO.Stream"/> and optionally releases the managed resources.
        /// </summary>
        /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            lock (this._incoming)
            {
                Monitor.Pulse(this._incoming);
            }

            if (this._channel != null)
            {
                this._channel.Dispose();
                this._channel = null;
            }
        }
Exemple #16
0
 private void SendConfirmation(ChannelSession channel)
 {
     this.SendData(channel, new byte[] { 0 });
 }
Exemple #17
0
 private void SendConfirmation(ChannelSession channel, byte errorCode, string message)
 {
     this.SendData(channel, new byte[] { errorCode });
     this.SendData(channel, string.Format("{0}\n", message));
 }
        private void CreateChannel()
        {
            this._channel = this._session.CreateChannel<ChannelSession>();
            this._channel.DataReceived += Channel_DataReceived;
            this._channel.ExtendedDataReceived += Channel_ExtendedDataReceived;
            this._channel.RequestReceived += Channel_RequestReceived;
            this._channel.Closed += Channel_Closed;

            //  Dispose of streams if already exists
            if (this.OutputStream != null)
            {
                this.OutputStream.Dispose();
                this.OutputStream = null;
            }

            if (this.ExtendedOutputStream != null)
            {
                this.ExtendedOutputStream.Dispose();
                this.ExtendedOutputStream = null;
            }

            //  Initialize output streams and StringBuilders
            this.OutputStream = new PipeStream();
            this.ExtendedOutputStream = new PipeStream();

            this._result = null;
            this._error = null;
        }
Exemple #19
0
 private void SendData(ChannelSession channel, byte[] buffer, int length)
 {
     if (length == buffer.Length)
     {
         channel.SendData(buffer);
     }
     else
     {
         channel.SendData(buffer.Take(length).ToArray());
     }
 }
Exemple #20
0
        /// <summary>
        /// Starts this shell.
        /// </summary>
        /// <exception cref="SshException">Shell is started.</exception>
        public void Start()
        {
            if (this.IsStarted)
            {
                throw new SshException("Shell is started.");
            }

            if (this.Starting != null)
            {
                this.Starting(this, new EventArgs());
            }

            this._channel = this._session.CreateClientChannel<ChannelSession>();
            this._channel.DataReceived += Channel_DataReceived;
            this._channel.ExtendedDataReceived += Channel_ExtendedDataReceived;
            this._channel.Closed += Channel_Closed;
            this._session.Disconnected += Session_Disconnected;
            this._session.ErrorOccured += Session_ErrorOccured;

            this._channel.Open();
            this._channel.SendPseudoTerminalRequest(this._terminalName, this._columns, this._rows, this._width, this._height, this._terminalModes);
            this._channel.SendShellRequest();

            this._channelClosedWaitHandle = new AutoResetEvent(false);

            //  Start input stream listener
            this._dataReaderTaskCompleted = new ManualResetEvent(false);
            this.ExecuteThread(() =>
            {
                try
                {
                    var buffer = new byte[this._bufferSize];

                    while (this._channel.IsOpen)
                    {
                        var asyncResult = this._input.BeginRead(buffer, 0, buffer.Length, delegate(IAsyncResult result)
                        {
                            //  If input stream is closed and disposed already dont finish reading the stream
                            if (this._input == null)
                                return;

                            var read = this._input.EndRead(result);
                            if (read > 0)
                            {
                                this._channel.SendData(buffer.Take(read).ToArray());
                            }

                        }, null);

                        EventWaitHandle.WaitAny(new WaitHandle[] { asyncResult.AsyncWaitHandle, this._channelClosedWaitHandle });

                        if (asyncResult.IsCompleted)
                            continue;
                        break;
                    }
                }
                catch (Exception exp)
                {
                    this.RaiseError(new ExceptionEventArgs(exp));
                }
                finally
                {
                    this._dataReaderTaskCompleted.Set();
                }
            });

            this.IsStarted = true;

            if (this.Started != null)
            {
                this.Started(this, new EventArgs());
            }
        }
Exemple #21
0
        private void InternalDownload(ChannelSession channel, Stream input, FileSystemInfo fileSystemInfo)
        {
            DateTime modifiedTime = DateTime.Now;
            DateTime accessedTime = DateTime.Now;

            var startDirectoryFullName = fileSystemInfo.FullName;
            var currentDirectoryFullName = startDirectoryFullName;
            var directoryCounter = 0;

            while (true)
            {
                var message = ReadString(input);

                if (message == "E")
                {
                    this.SendConfirmation(channel); //  Send reply

                    directoryCounter--;

                    currentDirectoryFullName = new DirectoryInfo(currentDirectoryFullName).Parent.FullName;

                    if (directoryCounter == 0)
                        break;
                    continue;
                }

                var match = _directoryInfoRe.Match(message);
                if (match.Success)
                {
                    this.SendConfirmation(channel); //  Send reply

                    //  Read directory
                    var mode = long.Parse(match.Result("${mode}"));
                    var filename = match.Result("${filename}");

                    DirectoryInfo newDirectoryInfo;
                    if (directoryCounter > 0)
                    {
                        newDirectoryInfo = Directory.CreateDirectory(string.Format("{0}{1}{2}", currentDirectoryFullName, Path.DirectorySeparatorChar, filename));
                        newDirectoryInfo.LastAccessTime = accessedTime;
                        newDirectoryInfo.LastWriteTime = modifiedTime;
                    }
                    else
                    {
                        //  Dont create directory for first level
                        newDirectoryInfo = fileSystemInfo as DirectoryInfo;
                    }

                    directoryCounter++;

                    currentDirectoryFullName = newDirectoryInfo.FullName;
                    continue;
                }

                match = _fileInfoRe.Match(message);
                if (match.Success)
                {
                    //  Read file
                    this.SendConfirmation(channel); //  Send reply

                    var mode = match.Result("${mode}");
                    var length = long.Parse(match.Result("${length}"));
                    var fileName = match.Result("${filename}");

                    var fileInfo = fileSystemInfo as FileInfo;

                    if (fileInfo == null)
                        fileInfo = new FileInfo(string.Format("{0}{1}{2}", currentDirectoryFullName, Path.DirectorySeparatorChar, fileName));

                    using (var output = fileInfo.OpenWrite())
                    {
                        this.InternalDownload(channel, input, output, fileName, length);
                    }

                    fileInfo.LastAccessTime = accessedTime;
                    fileInfo.LastWriteTime = modifiedTime;

                    if (directoryCounter == 0)
                        break;
                    continue;
                }

                match = _timestampRe.Match(message);
                if (match.Success)
                {
                    //  Read timestamp
                    this.SendConfirmation(channel); //  Send reply

                    var mtime = long.Parse(match.Result("${mtime}"));
                    var atime = long.Parse(match.Result("${atime}"));

                    var zeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
                    modifiedTime = zeroTime.AddSeconds(mtime);
                    accessedTime = zeroTime.AddSeconds(atime);
                    continue;
                }

                this.SendConfirmation(channel, 1, string.Format("\"{0}\" is not valid protocol message.", message));
            }
        }
Exemple #22
0
        private void Channel_Closed(object sender, ChannelEventArgs e)
        {
            if (this.Stopping != null)
            {
                //  Handle event on different thread
                this.ExecuteThread(() => this.Stopping(this, new EventArgs()));
            }

            if (this._channel.IsOpen)
            {
                this._channel.SendEof();

                this._channel.Close();
            }

            this._channelClosedWaitHandle.Set();

            this._input.Dispose();
            this._input = null;

            this._dataReaderTaskCompleted.WaitOne(this._session.ConnectionInfo.Timeout);
            this._dataReaderTaskCompleted.Dispose();
            this._dataReaderTaskCompleted = null;

            this._channel.DataReceived -= Channel_DataReceived;
            this._channel.ExtendedDataReceived -= Channel_ExtendedDataReceived;
            this._channel.Closed -= Channel_Closed;
            this._session.Disconnected -= Session_Disconnected;
            this._session.ErrorOccured -= Session_ErrorOccured;

            if (this.Stopped != null)
            {
                //  Handle event on different thread
                this.ExecuteThread(() => this.Stopped(this, new EventArgs()));
            }

            this._channel = null;
        }
Exemple #23
0
        private void InternalUpload(ChannelSession channel, PipeStream input, DirectoryInfo directoryInfo, string directoryName)
        {
            this.InternalSetTimestamp(channel, input, directoryInfo.LastWriteTimeUtc, directoryInfo.LastAccessTimeUtc);
            this.SendData(channel, string.Format("D0755 0 {0}\n", directoryName));
            this.CheckReturnCode(input);

            //  Upload files
            var files = directoryInfo.GetFiles();
            foreach (var file in files)
            {
                this.InternalUpload(channel, input, file, file.Name);
            }

            //  Upload directories
            var directories = directoryInfo.GetDirectories();
            foreach (var directory in directories)
            {
                this.InternalUpload(channel, input, directory, directory.Name);
            }

            this.SendData(channel, "E\n");
            this.CheckReturnCode(input);
        }
Exemple #24
0
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged ResourceMessages.</param>
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this._disposed)
            {
                // If disposing equals true, dispose all managed
                // and unmanaged ResourceMessages.
                if (disposing)
                {
                    if (this._channelClosedWaitHandle != null)
                    {
                        this._channelClosedWaitHandle.Dispose();
                        this._channelClosedWaitHandle = null;
                    }

                    if (this._channel != null)
                    {
                        this._channel.Dispose();
                        this._channel = null;
                    }

                    if (this._dataReaderTaskCompleted != null)
                    {
                        this._dataReaderTaskCompleted.Dispose();
                        this._dataReaderTaskCompleted = null;
                    }
                }

                // Note disposing has been done.
                this._disposed = true;
            }
        }
Exemple #25
0
        private void InternalDownload(ChannelSession channel, Stream input, Stream output, string filename, long length)
        {
            var buffer = new byte[Math.Min(length, this.BufferSize)];
            var needToRead = length;

            do
            {
                var read = input.Read(buffer, 0, (int)Math.Min(needToRead, this.BufferSize));

                output.Write(buffer, 0, read);

                this.RaiseDownloadingEvent(filename, length, length - needToRead);

                needToRead -= read;
            }
            while (needToRead > 0);

            output.Flush();

            //  Raise one more time when file downloaded
            this.RaiseDownloadingEvent(filename, length, length - needToRead);

            //  Send confirmation byte after last data byte was read
            this.SendConfirmation(channel);

            this.CheckReturnCode(input);
        }
Exemple #26
0
 private void InternalSetTimestamp(ChannelSession channel, Stream input, DateTime lastWriteTime, DateTime lastAccessime)
 {
     var zeroTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
     var modificationSeconds = (long)(lastWriteTime - zeroTime).TotalSeconds;
     var accessSeconds = (long)(lastAccessime - zeroTime).TotalSeconds;
     this.SendData(channel, string.Format("T{0} 0 {1} 0\n", modificationSeconds, accessSeconds));
     this.CheckReturnCode(input);
 }
        public void Connect()
        {
            this._channel = this._session.CreateChannel<ChannelSession>();

            this._session.ErrorOccured += Session_ErrorOccured;
            this._session.Disconnected += Session_Disconnected;
            this._channel.DataReceived += Channel_DataReceived;

            this._channel.Open();

            this._channel.SendSubsystemRequest("sftp");

            this.SendMessage(new SftpInitRequest(3));

            this.WaitHandle(this._sftpVersionConfirmed, this._operationTimeout);

            this.ProtocolVersion = 3;

            //  Resolve current directory
            this.WorkingDirectory = this.RequestRealPath(".").Keys.First();
        }
Exemple #28
0
        private void InternalUpload(ChannelSession channel, Stream input, Stream source, string filename)
        {
            var length = source.Length;

            this.SendData(channel, string.Format("C0644 {0} {1}\n", length, filename));

            var buffer = new byte[this.BufferSize];

            var read = source.Read(buffer, 0, buffer.Length);

            long totalRead = 0;

            while (read > 0)
            {
                this.SendData(channel, buffer, read);

                totalRead += read;

                this.RaiseUploadingEvent(filename, length, totalRead);

                read = source.Read(buffer, 0, buffer.Length);
            }

            this.SendConfirmation(channel);
            this.CheckReturnCode(input);
        }
        /// <summary>
        /// Releases unmanaged and - optionally - managed resources
        /// </summary>
        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
        protected virtual void Dispose(bool disposing)
        {
            // Check to see if Dispose has already been called.
            if (!this._isDisposed)
            {
                if (this._channel != null)
                {
                    this._channel.DataReceived -= Channel_DataReceived;

                    this._channel.Dispose();
                    this._channel = null;
                }

                this._session.ErrorOccured -= Session_ErrorOccured;
                this._session.Disconnected -= Session_Disconnected;

                // If disposing equals true, dispose all managed
                // and unmanaged resources.
                if (disposing)
                {
                    // Dispose managed resources.
                    if (this._errorOccuredWaitHandle != null)
                    {
                        this._errorOccuredWaitHandle.Dispose();
                        this._errorOccuredWaitHandle = null;
                    }
                }

                // Note disposing has been done.
                _isDisposed = true;
            }
        }
        private void Arrange()
        {
            var random = new Random();
            _localChannelNumber = (uint) random.Next(0, int.MaxValue);
            _localWindowSize = (uint) random.Next(2000, 3000);
            _localPacketSize = (uint) random.Next(1000, 2000);
            _initialSessionSemaphoreCount = random.Next(10, 20);
            _sessionSemaphore = new SemaphoreLight(_initialSessionSemaphoreCount);
            _channelClosedRegister = new List<ChannelEventArgs>();
            _channelExceptionRegister = new List<ExceptionEventArgs>();
            _actualException = null;

            _failureReasonCode = (uint)random.Next(0, int.MaxValue);
            _failureDescription = random.Next().ToString(CultureInfo.InvariantCulture);
            _failureLanguage = random.Next().ToString(CultureInfo.InvariantCulture);

            _sessionMock = new Mock<ISession>(MockBehavior.Strict);
            _connectionInfoMock = new Mock<IConnectionInfo>(MockBehavior.Strict);

            var sequence = new MockSequence();
            _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
            _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(1);
            _sessionMock.Setup(p => p.SessionSemaphore).Returns(_sessionSemaphore);
            _sessionMock.InSequence(sequence)
                .Setup(
                    p =>
                        p.SendMessage(
                            It.Is<ChannelOpenMessage>(
                                m =>
                                    m.LocalChannelNumber == _localChannelNumber &&
                                    m.InitialWindowSize == _localWindowSize && m.MaximumPacketSize == _localPacketSize &&
                                    m.Info is SessionChannelOpenInfo)));
            _sessionMock.InSequence(sequence)
                .Setup(p => p.WaitOnHandle(It.IsNotNull<WaitHandle>()))
                .Callback<WaitHandle>(
                    w =>
                        {
                            _sessionMock.Raise(
                                s => s.ChannelOpenFailureReceived += null,
                                new MessageEventArgs<ChannelOpenFailureMessage>(
                                    new ChannelOpenFailureMessage(
                                        _localChannelNumber,
                                        _failureDescription,
                                        _failureReasonCode,
                                        _failureLanguage
                                        )));
                        w.WaitOne();
                    });
            _sessionMock.InSequence(sequence).Setup(p => p.ConnectionInfo).Returns(_connectionInfoMock.Object);
            _connectionInfoMock.InSequence(sequence).Setup(p => p.RetryAttempts).Returns(1);

            _channel = new ChannelSession(_sessionMock.Object, _localChannelNumber, _localWindowSize, _localPacketSize);
            _channel.Closed += (sender, args) => _channelClosedRegister.Add(args);
            _channel.Exception += (sender, args) => _channelExceptionRegister.Add(args);
        }