mirror of
https://github.com/sshnet/SSH.NET.git
synced 2026-09-10 17:25:51 +00:00
Minor changes for future silverlight support
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using Renci.SshNet.Channels;
|
||||
|
||||
namespace Renci.SshNet
|
||||
{
|
||||
@@ -8,9 +12,85 @@ namespace Renci.SshNet
|
||||
/// </summary>
|
||||
public partial class ForwardedPortLocal
|
||||
{
|
||||
private TcpListener _listener;
|
||||
|
||||
partial void ExecuteThread(Action action)
|
||||
{
|
||||
Task.Factory.StartNew(action);
|
||||
}
|
||||
|
||||
partial void InternalStart()
|
||||
{
|
||||
// If port already started don't start it again
|
||||
if (this.IsStarted)
|
||||
return;
|
||||
|
||||
var ep = new IPEndPoint(Dns.GetHostAddresses(this.BoundHost)[0], (int)this.BoundPort);
|
||||
|
||||
this._listener = new TcpListener(ep);
|
||||
this._listener.Start();
|
||||
|
||||
this._listenerTaskCompleted = new ManualResetEvent(false);
|
||||
this.ExecuteThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var socket = this._listener.AcceptSocket();
|
||||
|
||||
this.ExecuteThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
IPEndPoint originatorEndPoint = socket.RemoteEndPoint as IPEndPoint;
|
||||
|
||||
this.RaiseRequestReceived(originatorEndPoint.Address.ToString(), (uint)originatorEndPoint.Port);
|
||||
|
||||
var channel = this.Session.CreateChannel<ChannelDirectTcpip>();
|
||||
|
||||
channel.Bind(this.Host, this.Port, socket);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
this.RaiseExceptionEvent(exp);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (SocketException exp)
|
||||
{
|
||||
if (!(exp.SocketErrorCode == SocketError.Interrupted))
|
||||
{
|
||||
this.RaiseExceptionEvent(exp);
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
this.RaiseExceptionEvent(exp);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this._listenerTaskCompleted.Set();
|
||||
}
|
||||
});
|
||||
|
||||
this.IsStarted = true;
|
||||
}
|
||||
|
||||
partial void InternalStop()
|
||||
{
|
||||
// If port not started you cant stop it
|
||||
if (!this.IsStarted)
|
||||
return;
|
||||
|
||||
this._listener.Stop();
|
||||
// TODO: Add timeout to WaitOne method
|
||||
this._listenerTaskCompleted.WaitOne();
|
||||
this._listenerTaskCompleted.Dispose();
|
||||
this._listenerTaskCompleted = null;
|
||||
|
||||
this.IsStarted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Renci.SshNet.Channels;
|
||||
using System.Threading;
|
||||
|
||||
namespace Renci.SshNet
|
||||
@@ -11,8 +8,6 @@ namespace Renci.SshNet
|
||||
/// </summary>
|
||||
public partial class ForwardedPortLocal : ForwardedPort, IDisposable
|
||||
{
|
||||
private TcpListener _listener;
|
||||
|
||||
private EventWaitHandle _listenerTaskCompleted;
|
||||
|
||||
/// <summary>
|
||||
@@ -20,61 +15,7 @@ namespace Renci.SshNet
|
||||
/// </summary>
|
||||
public override void Start()
|
||||
{
|
||||
// If port already started don't start it again
|
||||
if (this.IsStarted)
|
||||
return;
|
||||
|
||||
var ep = new IPEndPoint(Dns.GetHostAddresses(this.BoundHost)[0], (int)this.BoundPort);
|
||||
|
||||
this._listener = new TcpListener(ep);
|
||||
this._listener.Start();
|
||||
|
||||
this._listenerTaskCompleted = new ManualResetEvent(false);
|
||||
this.ExecuteThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var socket = this._listener.AcceptSocket();
|
||||
|
||||
this.ExecuteThread(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
IPEndPoint originatorEndPoint = socket.RemoteEndPoint as IPEndPoint;
|
||||
|
||||
this.RaiseRequestReceived(originatorEndPoint.Address.ToString(), (uint)originatorEndPoint.Port);
|
||||
|
||||
var channel = this.Session.CreateChannel<ChannelDirectTcpip>();
|
||||
|
||||
channel.Bind(this.Host, this.Port, socket);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
this.RaiseExceptionEvent(exp);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (SocketException exp)
|
||||
{
|
||||
if (!(exp.SocketErrorCode == SocketError.Interrupted))
|
||||
{
|
||||
this.RaiseExceptionEvent(exp);
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
this.RaiseExceptionEvent(exp);
|
||||
}
|
||||
finally
|
||||
{
|
||||
this._listenerTaskCompleted.Set();
|
||||
}
|
||||
});
|
||||
|
||||
this.IsStarted = true;
|
||||
this.InternalStart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -84,19 +25,13 @@ namespace Renci.SshNet
|
||||
{
|
||||
base.Stop();
|
||||
|
||||
// If port not started you cant stop it
|
||||
if (!this.IsStarted)
|
||||
return;
|
||||
|
||||
this._listener.Stop();
|
||||
// TODO: Add timeout to WaitOne method
|
||||
this._listenerTaskCompleted.WaitOne();
|
||||
this._listenerTaskCompleted.Dispose();
|
||||
this._listenerTaskCompleted = null;
|
||||
|
||||
this.IsStarted = false;
|
||||
this.InternalStop();
|
||||
}
|
||||
|
||||
partial void InternalStart();
|
||||
|
||||
partial void InternalStop();
|
||||
|
||||
partial void ExecuteThread(Action action);
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
@@ -10,10 +10,61 @@ namespace Renci.SshNet.Security.Cryptography
|
||||
/// </summary>
|
||||
public enum CipherModeEx
|
||||
{
|
||||
/// <summary>
|
||||
/// The Cipher Block Chaining (CBC) mode introduces feedback. Before each plain
|
||||
/// text block is encrypted, it is combined with the cipher text of the previous
|
||||
/// block by a bitwise exclusive OR operation. This ensures that even if the
|
||||
/// plain text contains many identical blocks, they will each encrypt to a different
|
||||
/// cipher text block. The initialization vector is combined with the first plain
|
||||
/// text block by a bitwise exclusive OR operation before the block is encrypted.
|
||||
/// If a single bit of the cipher text block is mangled, the corresponding plain
|
||||
/// text block will also be mangled. In addition, a bit in the subsequent block,
|
||||
/// in the same position as the original mangled bit, will be mangled.
|
||||
/// </summary>
|
||||
CBC = 1,
|
||||
/// <summary>
|
||||
/// The Electronic Codebook (ECB) mode encrypts each block individually. This
|
||||
/// means that any blocks of plain text that are identical and are in the same
|
||||
/// message, or in a different message encrypted with the same key, will be transformed
|
||||
/// into identical cipher text blocks. If the plain text to be encrypted contains
|
||||
/// substantial repetition, it is feasible for the cipher text to be broken one
|
||||
/// block at a time. Also, it is possible for an active adversary to substitute
|
||||
/// and exchange individual blocks without detection. If a single bit of the
|
||||
/// cipher text block is mangled, the entire corresponding plain text block will
|
||||
/// also be mangled.
|
||||
/// </summary>
|
||||
ECB = 2,
|
||||
/// <summary>
|
||||
/// The Output Feedback (OFB) mode processes small increments of plain text into
|
||||
/// cipher text instead of processing an entire block at a time. This mode is
|
||||
/// similar to CFB; the only difference between the two modes is the way that
|
||||
/// the shift register is filled. If a bit in the cipher text is mangled, the
|
||||
/// corresponding bit of plain text will be mangled. However, if there are extra
|
||||
/// or missing bits from the cipher text, the plain text will be mangled from
|
||||
/// that point on.
|
||||
/// </summary>
|
||||
OFB = 3,
|
||||
/// <summary>
|
||||
/// The Cipher Feedback (CFB) mode processes small increments of plain text into
|
||||
/// cipher text, instead of processing an entire block at a time. This mode uses
|
||||
/// a shift register that is one block in length and is divided into sections.
|
||||
/// For example, if the block size is eight bytes, with one byte processed at
|
||||
/// a time, the shift register is divided into eight sections. If a bit in the
|
||||
/// cipher text is mangled, one plain text bit is mangled and the shift register
|
||||
/// is corrupted. This results in the next several plain text increments being
|
||||
/// mangled until the bad bit is shifted out of the shift register.
|
||||
/// </summary>
|
||||
CFB = 4,
|
||||
/// <summary>
|
||||
/// The Cipher Text Stealing (CTS) mode handles any length of plain text and
|
||||
/// produces cipher text whose length matches the plain text length. This mode
|
||||
/// behaves like the CBC mode for all but the last two blocks of the plain text.
|
||||
/// </summary>
|
||||
CTS = 5,
|
||||
/// <summary>
|
||||
/// Counter Block Cipher mode
|
||||
/// </summary>
|
||||
CTR = 10, // make sure these don't overlap with ExpressionType
|
||||
CTR = 10,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user