Преглед изворни кода

Merge branch 'develop' of https://github.com/sshnet/SSH.NET.git

oleg пре 8 година
родитељ
комит
5b724e5001

+ 33 - 4
build/build.proj

@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Clean;CreatePackage;GenerateHelpFile" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Clean;CreateNuGetPackage;CreateBinPackage;GenerateHelpFile" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+	<UsingTask TaskName="Zip" AssemblyFile="$(MSBuildThisFileDirectory)target\nuget\packages\$(MSBuildTasksPackageId).$(MSBuildTasksPackageVersion)\tools\MSBuild.Community.Tasks.dll"/>
 	<PropertyGroup>
 		<Configuration Condition="'$(Configuration)' == ''">Release</Configuration>
 		<BuildRoot>$(MSBuildThisFileDirectory)</BuildRoot>
 		<NuGetExe>$(BuildRoot)target\nuget\nuget.exe</NuGetExe>
+		<MSBuildTasksPackageId>MSBuildTasks</MSBuildTasksPackageId>
+		<MSBuildTasksPackageVersion>1.5.0.214</MSBuildTasksPackageVersion>
 	</PropertyGroup>
 	<ItemGroup>
 		<VisualStudioVersion Include="2012">
@@ -76,7 +79,7 @@
 		</ItemGroup>
 		<MSBuild Projects="@(ProjectToBuild)" Targets="Rebuild"/>
 	</Target>
-	<Target Name="CreatePackage" DependsOnTargets="CopyBuildOutputToPackage">
+	<Target Name="CreateNuGetPackage" DependsOnTargets="CopyBuildOutputToPackage">
 		<Exec Command="$(NuGetExe) pack $(MSBuildThisFileDirectory)nuget\SSH.NET.nuspec -OutputDirectory &quot;$(MSBuildThisFileDirectory)target&quot; -BasePath &quot;$(MSBuildThisFileDirectory)target\package&quot; -NonInteractive"/>
 	</Target>
 	<Target Name="CopyBuildOutputToPackage" DependsOnTargets="Build" Outputs="%(TargetFramework.Identity)">
@@ -87,11 +90,37 @@
 		</ItemGroup>
 		<Copy SourceFiles="@(BuildOutput)" DestinationFolder="$(MSBuildThisFileDirectory)target\package\lib\%(TargetFramework.Moniker)"/>
 	</Target>
-	<Target Name="GenerateHelpFile" DependsOnTargets="Build">
+	<Target Name="GenerateHelpFile" DependsOnTargets="Build;CheckReleaseVersion">
 		<Error Text="Please install Sandcastle, and ensure the SHFBFolder environment variable is set." Condition="'$(SHFBFolder)'==''"/>
 		<MSBuild Projects="$(MSBuildThisFileDirectory)sandcastle\SSH.NET.shfbproj"/>
+		<Move SourceFiles="$(MSBuildThisFileDirectory)target\help\SshNet.Help.chm" DestinationFiles="$(MSBuildThisFileDirectory)target\SSH.NET-$(ReleaseVersion)-help.chm"/>
+	</Target>
+	<Target Name="CopyBuildOutputToBin" DependsOnTargets="Build" Outputs="%(TargetFramework.Identity)">
+		<ItemGroup>
+			<BuildOutput Remove="@(BuildOutput)"/>
+			<BuildOutput Include="$(MSBuildThisFileDirectory)..\src\%(TargetFramework.OutputDirectory)\*.dll"/>
+			<BuildOutput Include="$(MSBuildThisFileDirectory)..\src\%(TargetFramework.OutputDirectory)\*.xml"/>
+		</ItemGroup>
+		<Copy SourceFiles="@(BuildOutput)" DestinationFolder="$(MSBuildThisFileDirectory)target\bin\lib\%(TargetFramework.Moniker)"/>
+	</Target>
+	<Target Name="CreateBinPackage" DependsOnTargets="PrepareMSBuildTasksPackage;CopyBuildOutputToBin;CheckReleaseVersion">
+		<ItemGroup>
+			<Files Remove="@(Files)"/>
+			<Files Include="$(MSBuildThisFileDirectory)..\LICENSE"/>
+		</ItemGroup>
+		<Copy SourceFiles="@(Files)" DestinationFolder="$(MSBuildThisFileDirectory)target\bin\%(RecursiveDir)"/>
+		<ItemGroup>
+			<Files Remove="@(Files)"/>
+			<Files Include="$(MSBuildThisFileDirectory)target\bin\**"/>
+		</ItemGroup>
+		<Zip ZipFileName="$(MSBuildThisFileDirectory)target\SSH.NET-$(ReleaseVersion)-bin.zip" Files="@(Files)" WorkingDirectory="$(MSBuildThisFileDirectory)target\bin"/>
+	</Target>
+	<Target Name="PrepareMSBuildTasksPackage" DependsOnTargets="DownloadNuGet">
+		<Exec Command="$(NuGetExe) install $(MSBuildTasksPackageId) -Version $(MSBuildTasksPackageVersion) -OutputDirectory &quot;$(MSBuildThisFileDirectory)target\nuget\packages&quot; -Verbosity quiet"/>
+	</Target>
+	<Target Name="CheckReleaseVersion" Condition="'$(ReleaseVersion)'==''">
+		<Error Text= "Please specify the version number of the release (using the &quot;ReleaseVersion&quot; property)."/>
 	</Target>
-	
 	<UsingTask TaskName="DownloadFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
 		<ParameterGroup>
 			<Address ParameterType="System.String" Required="true"/>

+ 2 - 2
build/nuget/SSH.NET.nuspec

@@ -2,7 +2,7 @@
 <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
     <metadata>
         <id>SSH.NET</id>
-        <version>2016.0.0</version>
+        <version>2016.1.0-beta1</version>
         <title>SSH.NET</title>
         <authors>Renci</authors>
         <owners>olegkap,drieseng</owners>
@@ -10,7 +10,7 @@
         <projectUrl>https://github.com/sshnet/SSH.NET/</projectUrl>
         <requireLicenseAcceptance>false</requireLicenseAcceptance>
         <description>SSH.NET is a Secure Shell (SSH) library for .NET, optimized for parallelism and with broad framework support.</description>
-        <releaseNotes>https://github.com/sshnet/SSH.NET/releases/tag/2016.0.0</releaseNotes>
+        <releaseNotes>https://github.com/sshnet/SSH.NET/releases/tag/2016.1.0-beta1</releaseNotes>
         <summary>A Secure Shell (SSH) library for .NET, optimized for parallelism.</summary>
         <copyright>2012-2016, RENCI</copyright>
         <language>en-US</language>

+ 71 - 0
build/sandcastle/new.shfbproj

@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <!-- The configuration and platform will be used to determine which assemblies to include from solution and
+				 project documentation sources -->
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{6c35cd41-3f6e-47c1-a805-1aab0ac88b36}</ProjectGuid>
+    <SHFBSchemaVersion>2015.6.5.0</SHFBSchemaVersion>
+    <!-- AssemblyName, Name, and RootNamespace are not used by SHFB but Visual Studio adds them anyway -->
+    <AssemblyName>Documentation</AssemblyName>
+    <RootNamespace>Documentation</RootNamespace>
+    <Name>Documentation</Name>
+    <!-- SHFB properties -->
+    <FrameworkVersion>.NET Framework 4.0</FrameworkVersion>
+    <OutputPath>D:\development\SSH.NET\build\target\help\</OutputPath>
+    <HtmlHelpName>Documentation</HtmlHelpName>
+    <Language>en-US</Language>
+    <SaveComponentCacheCapacity>100</SaveComponentCacheCapacity>
+    <BuildAssemblerVerbosity>OnlyWarningsAndErrors</BuildAssemblerVerbosity>
+    <HelpFileFormat>Markdown</HelpFileFormat>
+    <IndentHtml>False</IndentHtml>
+    <KeepLogFile>False</KeepLogFile>
+    <DisableCodeBlockComponent>False</DisableCodeBlockComponent>
+    <CleanIntermediates>True</CleanIntermediates>
+    <DocumentationSources>
+      <DocumentationSource sourceFile="D:\development\SSH.NET\src\Renci.SshNet\bin\Debug\Renci.SshNet.dll" />
+<DocumentationSource sourceFile="D:\development\SSH.NET\src\Renci.SshNet\bin\Debug\Renci.SshNet.xml" /></DocumentationSources>
+    <HelpFileVersion>1.0.0.0</HelpFileVersion>
+    <MaximumGroupParts>2</MaximumGroupParts>
+    <NamespaceGrouping>False</NamespaceGrouping>
+    <SyntaxFilters>Standard</SyntaxFilters>
+    <SdkLinkTarget>Blank</SdkLinkTarget>
+    <RootNamespaceContainer>False</RootNamespaceContainer>
+    <PresentationStyle>Markdown</PresentationStyle>
+    <Preliminary>False</Preliminary>
+    <NamingMethod>Guid</NamingMethod>
+    <HelpTitle>A Sandcastle Documented Class Library</HelpTitle>
+    <ContentPlacement>AboveNamespaces</ContentPlacement>
+  </PropertyGroup>
+  <!-- There are no properties for these groups.  AnyCPU needs to appear in order for Visual Studio to perform
+			 the build.  The others are optional common platform types that may appear. -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
+  </PropertyGroup>
+  <!-- Import the SHFB build targets -->
+  <Import Project="$(SHFBROOT)\SandcastleHelpFileBuilder.targets" />
+  <!-- The pre-build and post-build event properties must appear *after* the targets file import in order to be
+			 evaluated correctly. -->
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+    <PostBuildEvent>
+    </PostBuildEvent>
+    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
+  </PropertyGroup>
+</Project>

+ 1 - 2
src/Renci.SshNet.Silverlight/Renci.SshNet.Silverlight.csproj

@@ -55,7 +55,6 @@
     <AssemblyOriginatorKeyFile>..\Renci.SshNet.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Microsoft.CSharp, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
     <Reference Include="mscorlib" />
     <Reference Include="SshNet.Security.Cryptography">
       <HintPath>..\..\packages\SshNet.Security.Cryptography.1.2.0\lib\sl4\SshNet.Security.Cryptography.dll</HintPath>
@@ -917,7 +916,7 @@
       <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
         <SilverlightProjectProperties />
       </FlavorProperties>
-      <UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
+      <UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
     </VisualStudio>
   </ProjectExtensions>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+ 1 - 2
src/Renci.SshNet.Silverlight5/Renci.SshNet.Silverlight5.csproj

@@ -60,7 +60,6 @@
     <AssemblyOriginatorKeyFile>..\Renci.SshNet.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Microsoft.CSharp, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
     <Reference Include="mscorlib" />
     <Reference Include="SshNet.Security.Cryptography, Version=1.2.0.0, Culture=neutral, PublicKeyToken=2fa9220ff3eadda4, processorArchitecture=MSIL">
       <HintPath>..\..\packages\SshNet.Security.Cryptography.1.2.0\lib\sl5\SshNet.Security.Cryptography.dll</HintPath>
@@ -923,7 +922,7 @@
       <FlavorProperties GUID="{A1591282-1198-4647-A2B1-27E5FF5F6F3B}">
         <SilverlightProjectProperties />
       </FlavorProperties>
-      <UserProperties ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" />
+      <UserProperties ProjectLinkReference="2f5f8c90-0bd1-424f-997c-7bc6280919d1" ProjectLinkerExcludeFilter="\\?desktop(\\.*)?$;\\?silverlight(\\.*)?$;\.desktop;\.silverlight;\.xaml;^service references(\\.*)?$;\.clientconfig;^web references(\\.*)?$" />
     </VisualStudio>
   </ProjectExtensions>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+ 1 - 17
src/Renci.SshNet.Tests/Classes/ForwardedPortDynamicTest_Stop_PortDisposed.cs

@@ -13,7 +13,6 @@ namespace Renci.SshNet.Tests.Classes
         private ForwardedPortDynamic _forwardedPort;
         private IList<EventArgs> _closingRegister;
         private IList<ExceptionEventArgs> _exceptionRegister;
-        private ObjectDisposedException _actualException;
         private IPEndPoint _endpoint;
 
         [TestInitialize]
@@ -47,22 +46,7 @@ namespace Renci.SshNet.Tests.Classes
 
         protected void Act()
         {
-            try
-            {
-                _forwardedPort.Stop();
-                Assert.Fail();
-            }
-            catch (ObjectDisposedException ex)
-            {
-                _actualException = ex;
-            }
-        }
-
-        [TestMethod]
-        public void StopShouldThrowObjectDisposedException()
-        {
-            Assert.IsNotNull(_actualException);
-            Assert.AreEqual(_forwardedPort.GetType().FullName, _actualException.ObjectName);
+            _forwardedPort.Stop();
         }
 
         [TestMethod]

+ 1 - 17
src/Renci.SshNet.Tests/Classes/ForwardedPortLocalTest_Stop_PortDisposed.cs

@@ -11,7 +11,6 @@ namespace Renci.SshNet.Tests.Classes
         private ForwardedPortLocal _forwardedPort;
         private IList<EventArgs> _closingRegister;
         private IList<ExceptionEventArgs> _exceptionRegister;
-        private ObjectDisposedException _actualException;
 
         [TestInitialize]
         public void Setup()
@@ -43,22 +42,7 @@ namespace Renci.SshNet.Tests.Classes
 
         protected void Act()
         {
-            try
-            {
-                _forwardedPort.Stop();
-                Assert.Fail();
-            }
-            catch (ObjectDisposedException ex)
-            {
-                _actualException = ex;
-            }
-        }
-
-        [TestMethod]
-        public void StopShouldThrowObjectDisposedException()
-        {
-            Assert.IsNotNull(_actualException);
-            Assert.AreEqual(_forwardedPort.GetType().FullName, _actualException.ObjectName);
+            _forwardedPort.Stop();
         }
 
         [TestMethod]

+ 1 - 17
src/Renci.SshNet.Tests/Classes/ForwardedPortRemoteTest_Stop_PortDisposed.cs

@@ -14,7 +14,6 @@ namespace Renci.SshNet.Tests.Classes
         private IPEndPoint _remoteEndpoint;
         private IList<EventArgs> _closingRegister;
         private IList<ExceptionEventArgs> _exceptionRegister;
-        private ObjectDisposedException _actualException;
 
         [TestInitialize]
         public void Setup()
@@ -49,22 +48,7 @@ namespace Renci.SshNet.Tests.Classes
 
         protected void Act()
         {
-            try
-            {
-                _forwardedPort.Stop();
-                Assert.Fail();
-            }
-            catch (ObjectDisposedException ex)
-            {
-                _actualException = ex;
-            }
-        }
-
-        [TestMethod]
-        public void StopShouldThrowObjectDisposedException()
-        {
-            Assert.IsNotNull(_actualException);
-            Assert.AreEqual(_forwardedPort.GetType().FullName, _actualException.ObjectName);
+            _forwardedPort.Stop();
         }
 
         [TestMethod]

+ 0 - 2
src/Renci.SshNet.Tests/Classes/Sftp/SftpSessionTest_Connected_RequestRead.cs

@@ -1,14 +1,12 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
-using System.Runtime.InteropServices;
 using System.Text;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Moq;
 using Renci.SshNet.Channels;
 using Renci.SshNet.Common;
 using Renci.SshNet.Sftp;
-using Renci.SshNet.Sftp.Responses;
 
 namespace Renci.SshNet.Tests.Classes.Sftp
 {

+ 0 - 1
src/Renci.SshNet.Tests/Renci.SshNet.Tests.csproj

@@ -41,7 +41,6 @@
     <AssemblyOriginatorKeyFile>..\Renci.SshNet.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Microsoft.CSharp" />
     <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
     <Reference Include="Moq">
       <HintPath>..\..\packages\Moq.4.2.1409.1722\lib\net40\Moq.dll</HintPath>

+ 2 - 1
src/Renci.SshNet/Abstractions/DiagnosticAbstraction.cs

@@ -1,4 +1,5 @@
-using System.Diagnostics;
+using System;
+using System.Diagnostics;
 #if FEATURE_DIAGNOSTICS_TRACESOURCE
 using System.Threading;
 #endif // FEATURE_DIAGNOSTICS_TRACESOURCE

+ 2 - 2
src/Renci.SshNet/BaseClient.cs

@@ -222,7 +222,7 @@ namespace Renci.SshNet
         /// <exception cref="ObjectDisposedException">The method was called after the client was disposed.</exception>
         public void Disconnect()
         {
-            DiagnosticAbstraction.Log(string.Format("{0} Disconnecting client", DateTime.Now.Ticks));
+            DiagnosticAbstraction.Log("Disconnecting client.");
 
             CheckDisposed();
 
@@ -319,7 +319,7 @@ namespace Renci.SshNet
         /// </summary>
         public void Dispose()
         {
-            DiagnosticAbstraction.Log(string.Format("{0} Disposing client", DateTime.Now.Ticks));
+            DiagnosticAbstraction.Log("Disposing client.");
 
             Dispose(true);
             GC.SuppressFinalize(this);

+ 0 - 18
src/Renci.SshNet/Common/SshData.cs

@@ -255,24 +255,6 @@ namespace Renci.SshNet.Common
             return _stream.ReadBinary();
         }
 
-        //protected byte[] ReadBinaryDebug()
-        //{
-        //    DiagnosticAbstraction.Log("Stream Position:" + _stream.Position);
-        //    var data = _stream.ReadBytes(4);
-        //    DiagnosticAbstraction.Log("Binary Length Bytes:" + Session.ToHex(data, 0));
-        //    var length = (uint)(data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]);
-        //    DiagnosticAbstraction.Log("Binary Length:" + length);
-
-        //    if (length > int.MaxValue)
-        //    {
-        //        throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "Data longer than {0} is not supported.", int.MaxValue));
-        //    }
-
-        //    var binary = _stream.ReadBytes((int) length);
-        //    DiagnosticAbstraction.Log("Binary Bytes:" + Session.ToHex(binary, 0));
-        //    return binary;
-        //}
-
         /// <summary>
         /// Reads next name-list data type from internal buffer.
         /// </summary>

+ 0 - 2
src/Renci.SshNet/ForwardedPort.cs

@@ -71,8 +71,6 @@ namespace Renci.SshNet
         /// </summary>
         public virtual void Stop()
         {
-            CheckDisposed();
-
             if (IsStarted)
             {
                 StopPort(Session.ConnectionInfo.Timeout);

+ 72 - 60
src/Renci.SshNet/ForwardedPortDynamic.NET.cs

@@ -435,106 +435,118 @@ namespace Renci.SshNet
                 return false;
             }
 
-            IPAddress ipAddress;
-            byte[] addressBuffer;
+            var host = GetSocks5Host(addressType, socket, timeout);
+            if (host == null)
+            {
+                // SOCKS client closed connection
+                return false;
+            }
+
+            var portBuffer = new byte[2];
+            if (SocketAbstraction.Read(socket, portBuffer, 0, portBuffer.Length, timeout) == 0)
+            {
+                // SOCKS client closed connection
+                return false;
+            }
+
+            var port = (uint)(portBuffer[0] * 256 + portBuffer[1]);
+
+            RaiseRequestReceived(host, port);
+
+            channel.Open(host, port, this, socket);
+
+            var socksReply = CreateSocks5Reply(channel.IsOpen);
+
+            SocketAbstraction.Send(socket, socksReply, 0, socksReply.Length);
+
+            return true;
+        }
+
+        private static string GetSocks5Host(int addressType, Socket socket, TimeSpan timeout)
+        {
             switch (addressType)
             {
-                case 0x01:
+                case 0x01: // IPv4
                     {
-                        addressBuffer = new byte[4];
+                        var addressBuffer = new byte[4];
                         if (SocketAbstraction.Read(socket, addressBuffer, 0, 4, timeout) == 0)
                         {
                             // SOCKS client closed connection
-                            return false;
+                            return null;
                         }
 
-                        ipAddress = new IPAddress(addressBuffer);
+                        var ipv4 = new IPAddress(addressBuffer);
+                        return ipv4.ToString();
                     }
-                    break;
-                case 0x03:
+                case 0x03: // Domain name
                     {
                         var length = SocketAbstraction.ReadByte(socket, timeout);
                         if (length == -1)
                         {
                             // SOCKS client closed connection
-                            return false;
+                            return null;
                         }
-                        addressBuffer = new byte[length];
+                        var addressBuffer = new byte[length];
                         if (SocketAbstraction.Read(socket, addressBuffer, 0, addressBuffer.Length, timeout) == 0)
                         {
                             // SOCKS client closed connection
-                            return false;
+                            return null;
                         }
 
-                        ipAddress = IPAddress.Parse(SshData.Ascii.GetString(addressBuffer, 0, addressBuffer.Length));
-
-                        //var hostName = new Common.ASCIIEncoding().GetString(addressBuffer);
-
-                        //ipAddress = Dns.GetHostEntry(hostName).AddressList[0];
+                        var hostName = SshData.Ascii.GetString(addressBuffer, 0, addressBuffer.Length);
+                        return hostName;
                     }
-                    break;
-                case 0x04:
+                case 0x04: // IPv6
                     {
-                        addressBuffer = new byte[16];
+                        var addressBuffer = new byte[16];
                         if (SocketAbstraction.Read(socket, addressBuffer, 0, 16, timeout) == 0)
                         {
                             // SOCKS client closed connection
-                            return false;
+                            return null;
                         }
 
-                        ipAddress = new IPAddress(addressBuffer);
+                        var ipv6 = new IPAddress(addressBuffer);
+                        return ipv6.ToString();
                     }
-                    break;
                 default:
                     throw new ProxyException(string.Format("SOCKS5: Address type '{0}' is not supported.", addressType));
             }
+        }
 
-            var portBuffer = new byte[2];
-            if (SocketAbstraction.Read(socket, portBuffer, 0, portBuffer.Length, timeout) == 0)
-            {
-                // SOCKS client closed connection
-                return false;
-            }
-
-            var port = (uint)(portBuffer[0] * 256 + portBuffer[1]);
-            var host = ipAddress.ToString();
-
-            RaiseRequestReceived(host, port);
-
-            channel.Open(host, port, this, socket);
-
-            SocketAbstraction.SendByte(socket, 0x05);
-
-            if (channel.IsOpen)
-            {
-                SocketAbstraction.SendByte(socket, 0x00);
+        private static byte[] CreateSocks5Reply(bool channelOpen)
+        {
+            var socksReply = new byte[
+                // SOCKS version
+                1 +
+                // Reply field
+                1 +
+                // Reserved; fixed: 0x00
+                1 +
+                // Address type; fixed: 0x01
+                1 +
+                // IPv4 server bound address; fixed: {0x00, 0x00, 0x00, 0x00}
+                4 +
+                // server bound port; fixed: {0x00, 0x00}
+                2];
+
+            socksReply[0] = 0x05;
+
+            if (channelOpen)
+            {
+                socksReply[1] = 0x00; // succeeded
             }
             else
             {
-                SocketAbstraction.SendByte(socket, 0x01);
+                socksReply[1] = 0x01; // general SOCKS server failure
             }
 
             // reserved
-            SocketAbstraction.SendByte(socket, 0x00);
-
-            if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
-            {
-                SocketAbstraction.SendByte(socket, 0x01);
-            }
-            else if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
-            {
-                SocketAbstraction.SendByte(socket, 0x04);
-            }
-            else
-            {
-                throw new NotSupportedException("Not supported address family.");
-            }
+            socksReply[2] = 0x00;
 
-            var addressBytes = ipAddress.GetAddressBytes();
-            SocketAbstraction.Send(socket, addressBytes, 0, addressBytes.Length);
-            SocketAbstraction.Send(socket, portBuffer, 0, portBuffer.Length);
+            // IPv4 address type
+            socksReply[3] = 0x01;
 
-            return true;
+            return socksReply;
         }
 
         /// <summary>

+ 3 - 3
src/Renci.SshNet/Properties/CommonAssemblyInfo.cs

@@ -9,9 +9,9 @@ using System.Runtime.InteropServices;
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
-[assembly: AssemblyVersion("2016.0.0")]
-[assembly: AssemblyFileVersion("2016.0.0")]
-[assembly: AssemblyInformationalVersion("2016.0.0")]
+[assembly: AssemblyVersion("2016.1.0")]
+[assembly: AssemblyFileVersion("2016.1.0")]
+[assembly: AssemblyInformationalVersion("2016.1.0-beta1")]
 [assembly: CLSCompliant(false)]
 
 // Setting ComVisible to false makes the types in this assembly not visible 

+ 0 - 1
src/Renci.SshNet/Renci.SshNet.csproj

@@ -46,7 +46,6 @@
   <ItemGroup>
     <Reference Include="System" />
     <Reference Include="System.Core" />
-    <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>

+ 6 - 3
src/Renci.SshNet/ScpClient.NET.cs

@@ -63,16 +63,19 @@ namespace Renci.SshNet
                 channel.DataReceived += (sender, e) => input.Write(e.Data, 0, e.Data.Length);
                 channel.Open();
 
-                //  Send channel command request
+                // start recursive upload
                 channel.SendExecRequest(string.Format("scp -rt \"{0}\"", path));
                 CheckReturnCode(input);
 
+                // set last write and last access time on specified remote path
                 InternalSetTimestamp(channel, input, directoryInfo.LastWriteTimeUtc, directoryInfo.LastAccessTimeUtc);
-                SendData(channel, string.Format("D0755 0 {0}\n", Path.GetFileName(path)));
+                SendData(channel, string.Format("D0755 0 {0}\n", "."));
                 CheckReturnCode(input);
 
+                // recursively upload files and directories in specified remote path
                 InternalUpload(channel, input, directoryInfo);
 
+                // terminate upload of specified remote path
                 SendData(channel, "E\n");
                 CheckReturnCode(input);
             }
@@ -156,7 +159,7 @@ namespace Renci.SshNet
             var directories = directoryInfo.GetDirectories();
             foreach (var directory in directories)
             {
-                InternalSetTimestamp(channel, input, directoryInfo.LastWriteTimeUtc, directoryInfo.LastAccessTimeUtc);
+                InternalSetTimestamp(channel, input, directory.LastWriteTimeUtc, directory.LastAccessTimeUtc);
                 SendData(channel, string.Format("D0755 0 {0}\n", directory.Name));
                 CheckReturnCode(input);
 

+ 4 - 0
src/Renci.SshNet/ScpClient.cs

@@ -12,6 +12,10 @@ namespace Renci.SshNet
     /// <summary>
     /// Provides SCP client functionality.
     /// </summary>
+    /// <remarks>
+    /// More information on the SCP protocol is available here:
+    /// https://github.com/net-ssh/net-scp/blob/master/lib/net/scp.rb
+    /// </remarks>
     public partial class ScpClient : BaseClient
     {
         private static readonly Regex FileInfoRe = new Regex(@"C(?<mode>\d{4}) (?<length>\d+) (?<filename>.+)");

+ 10 - 34
src/Renci.SshNet/Session.cs

@@ -697,7 +697,7 @@ namespace Renci.SshNet
         /// </remarks>
         public void Disconnect()
         {
-            DiagnosticAbstraction.Log(string.Format("[{0}] {1} Disconnecting session", ToHex(SessionId), DateTime.Now.Ticks));
+            DiagnosticAbstraction.Log(string.Format("[{0}] Disconnecting session.", ToHex(SessionId)));
 
             // send SSH_MSG_DISCONNECT message, clear socket read buffer and dispose it
             Disconnect(DisconnectReason.ByApplication, "Connection terminated by the client.");
@@ -843,7 +843,7 @@ namespace Renci.SshNet
                 WaitOnHandle(_keyExchangeCompletedWaitHandle);
             }
 
-            DiagnosticAbstraction.Log(string.Format("[{0}] SendMessage to server '{1}': '{2}'.", ToHex(SessionId), message.GetType().Name, message));
+            DiagnosticAbstraction.Log(string.Format("[{0}] Sending message '{1}' to server: '{2}'.", ToHex(SessionId), message.GetType().Name, message));
 
             var paddingMultiplier = _clientCipher == null ? (byte) 8 : Math.Max((byte) 8, _serverCipher.MinimumSize);
             var packetData = message.GetPacket(paddingMultiplier, _clientCompression);
@@ -947,12 +947,12 @@ namespace Renci.SshNet
             }
             catch (SshException ex)
             {
-                DiagnosticAbstraction.Log(string.Format("Failure sending message server '{0}': '{1}' => {2}", message.GetType().Name, message, ex));
+                DiagnosticAbstraction.Log(string.Format("Failure sending message '{0}' to server: '{1}' => {2}", message.GetType().Name, message, ex));
                 return false;
             }
             catch (SocketException ex)
             {
-                DiagnosticAbstraction.Log(string.Format("Failure sending message server '{0}': '{1}' => {2}", message.GetType().Name, message, ex));
+                DiagnosticAbstraction.Log(string.Format("Failure sending message '{0}' to server: '{1}' => {2}", message.GetType().Name, message, ex));
                 return false;
             }
         }
@@ -998,16 +998,9 @@ namespace Renci.SshNet
                     return null;
                 }
 
-#if DEBUG_GERT
-                DiagnosticAbstraction.Log(string.Format("[{0}] FirstBlock [{1}]: {2}", ToHex(SessionId), blockSize, ToHex(firstBlock)));
-#endif // DEBUG_GERT
-
                 if (_serverCipher != null)
                 {
                     firstBlock = _serverCipher.Decrypt(firstBlock);
-#if DEBUG_GERT
-                    DiagnosticAbstraction.Log(string.Format("[{0}] FirstBlock decrypted [{1}]: {2}", ToHex(SessionId), firstBlock.Length, ToHex(firstBlock)));
-#endif // DEBUG_GERT
                 }
 
                 packetLength = (uint) (firstBlock[0] << 24 | firstBlock[1] << 16 | firstBlock[2] << 8 | firstBlock[3]);
@@ -1053,16 +1046,8 @@ namespace Renci.SshNet
                 var numberOfBytesToDecrypt = data.Length - (blockSize + inboundPacketSequenceLength + serverMacLength);
                 if (numberOfBytesToDecrypt > 0)
                 {
-#if DEBUG_GERT
-                    DiagnosticAbstraction.Log(string.Format("[{0}] NextBlocks [{1}]: {2}", ToHex(SessionId), bytesToRead, ToHex(nextBlocks)));
-#endif // DEBUG_GERT
-
                     var decryptedData = _serverCipher.Decrypt(data, blockSize + inboundPacketSequenceLength, numberOfBytesToDecrypt);
                     Buffer.BlockCopy(decryptedData, 0, data, blockSize + inboundPacketSequenceLength, decryptedData.Length);
-
-#if DEBUG_GERT
-                    DiagnosticAbstraction.Log(string.Format("[{0}] NextBlocks decrypted [{1}]: {2}", ToHex(SessionId), decryptedData.Length, ToHex(decryptedData)));
-#endif // DEBUG_GERT
                 }
             }
 
@@ -1092,10 +1077,6 @@ namespace Renci.SshNet
                 messagePayloadLength = data.Length;
             }
 
-#if DEBUG_GERT
-            DiagnosticAbstraction.Log(string.Format("[{0}] Message info (Sequence:{1},MessagePayloadLength:{2})", ToHex(SessionId), _inboundPacketSequence, messagePayloadLength));
-#endif // DEBUG_GERT
-
             _inboundPacketSequence++;
 
             return LoadMessage(data, messagePayloadOffset, messagePayloadLength);
@@ -1120,7 +1101,7 @@ namespace Renci.SshNet
         /// <param name="message"><see cref="DisconnectMessage"/> message.</param>
         internal void OnDisconnectReceived(DisconnectMessage message)
         {
-            DiagnosticAbstraction.Log(string.Format("[{0}] {1} Disconnect received: {2} {3}", ToHex(SessionId), DateTime.Now.Ticks, message.ReasonCode, message.Description));
+            DiagnosticAbstraction.Log(string.Format("[{0}] Disconnect received: {1} {2}.", ToHex(SessionId), message.ReasonCode, message.Description));
 
             // transition to disconnecting state to avoid throwing exceptions while cleaning up, and to
             // ensure any exceptions that are raised do not overwrite the SshConnectionException that we
@@ -1578,14 +1559,9 @@ namespace Renci.SshNet
             var messageType = data[offset];
 
             var message = _sshMessageFactory.Create(messageType);
-
-#if DEBUG_GERT
-            DiagnosticAbstraction.Log(string.Format("[{0}] Loading message with offset '{1}': {2}", ToHex(SessionId), offset, ToHex(data, 0)));
-#endif // DEBUG_GERT
-
             message.Load(data, offset + 1, count - 1);
 
-            DiagnosticAbstraction.Log(string.Format("[{0}] ReceiveMessage from server: '{1}': '{2}'.", ToHex(SessionId), message.GetType().Name, message));
+            DiagnosticAbstraction.Log(string.Format("[{0}] Received message '{1}' from server: '{2}'.", ToHex(SessionId), message.GetType().Name, message));
 
             return message;
         }
@@ -1627,7 +1603,7 @@ namespace Renci.SshNet
             var ipAddress = DnsAbstraction.GetHostAddresses(host)[0];
             var ep = new IPEndPoint(ipAddress, port);
 
-            DiagnosticAbstraction.Log(string.Format("Initiating connect to '{0}:{1}'.", host, port));
+            DiagnosticAbstraction.Log(string.Format("Initiating connection to '{0}:{1}'.", host, port));
 
             _socket = SocketAbstraction.Connect(ep, ConnectionInfo.Timeout);
 
@@ -2209,7 +2185,7 @@ namespace Renci.SshNet
         {
             var connectionException = exp as SshConnectionException;
 
-            DiagnosticAbstraction.Log(string.Format("[{0}] {1} Raised exception: {2}", ToHex(SessionId), DateTime.Now.Ticks, exp));
+            DiagnosticAbstraction.Log(string.Format("[{0}] Raised exception: {1}", ToHex(SessionId), exp));
 
             if (_isDisconnecting)
             {
@@ -2234,7 +2210,7 @@ namespace Renci.SshNet
 
             if (connectionException != null)
             {
-                DiagnosticAbstraction.Log(string.Format("[{0}] {1} Disconnecting after exception: {2}", ToHex(SessionId), DateTime.Now.Ticks, exp));
+                DiagnosticAbstraction.Log(string.Format("[{0}] Disconnecting after exception: {1}", ToHex(SessionId), exp));
                 Disconnect(connectionException.DisconnectReason, exp.ToString());
             }
         }
@@ -2290,7 +2266,7 @@ namespace Renci.SshNet
 
             if (disposing)
             {
-                DiagnosticAbstraction.Log(string.Format("[{0}] Disposing session", ToHex(SessionId)));
+                DiagnosticAbstraction.Log(string.Format("[{0}] Disposing session.", ToHex(SessionId)));
 
                 Disconnect();
 

+ 3 - 4
src/Renci.SshNet/Sftp/SftpSession.cs

@@ -1,5 +1,4 @@
 using System;
-using System.Linq;
 using System.Text;
 using System.Threading;
 using Renci.SshNet.Common;
@@ -90,7 +89,7 @@ namespace Renci.SshNet.Sftp
 
             if (realPathFiles != null)
             {
-                canonizedPath = realPathFiles.First().Key;
+                canonizedPath = realPathFiles[0].Key;
             }
 
             if (!string.IsNullOrEmpty(canonizedPath))
@@ -114,7 +113,7 @@ namespace Renci.SshNet.Sftp
 
             if (realPathFiles != null)
             {
-                canonizedPath = realPathFiles.First().Key;
+                canonizedPath = realPathFiles[0].Key;
             }
 
             if (string.IsNullOrEmpty(canonizedPath))
@@ -158,7 +157,7 @@ namespace Renci.SshNet.Sftp
             }
 
             //  Resolve current directory
-            WorkingDirectory = RequestRealPath(".").First().Key;
+            WorkingDirectory = RequestRealPath(".")[0].Key;
         }
 
         protected override void OnDataReceived(byte[] data)