Add ForceDataPort configuration

Use StaticDataConnection
This commit is contained in:
2019-07-20 14:31:33 +02:00
parent b2189e63df
commit 01fbd0b74e
8 changed files with 156 additions and 23 deletions

View File

@@ -108,7 +108,7 @@ namespace DearFTP.Configurations
public void Save()
{
var serializer = new SerializerBuilder().EmitDefaults().Build();
var serializer = new SerializerBuilder().Build();
File.WriteAllText(ConfigurationPath, serializer.Serialize(this));
}

View File

@@ -7,6 +7,7 @@ namespace DearFTP.Configurations
class ServerConfiguration
{
public ushort Port { get; set; } = 21;
public ushort ForceDataPort { get; set; } = 0;
public string MOTD { get; set; } = "DearFTP v0.1";
public string LoginMessage { get; set; } = "Logged in as %user%";

View File

@@ -16,11 +16,11 @@ namespace DearFTP.Connection.Commands
switch (argument.ToUpper())
{
case "C":
session.DataConnection.DesactivateTsl();
session.DataConnection.DesactivateTls();
stream.Send(ResponseCode.OK, "Data protection cleared.");
break;
case "P":
session.DataConnection.ActivateTsl();
session.DataConnection.ActivateTls();
stream.Send(ResponseCode.OK, "Data protection set.");
break;
default:

View File

@@ -11,15 +11,14 @@ using System.Threading.Tasks;
namespace DearFTP.Connection
{
class DataConnection
class DynamicDataConnection : IDataConnection
{
public const int Timeout = 100_000;
public const int Timeout = 10_000;
public TcpListener Listener { get; private set; }
public TcpClient Client { get; private set; }
public Stream Stream { get; private set; }
public bool IsTslProtected { get; private set; }
public int Port => ((IPEndPoint)Listener.LocalEndpoint).Port;
public int Port => ((IPEndPoint)_listener.LocalEndpoint).Port;
public bool IsAvailable
{
get
@@ -41,9 +40,11 @@ namespace DearFTP.Connection
}
}
private TcpListener _listener;
private TcpClient _client;
private Task _acceptTask;
public DataConnection()
public DynamicDataConnection()
{
IsTslProtected = false;
}
@@ -51,41 +52,41 @@ namespace DearFTP.Connection
public void Create()
{
// Clean old connections
if (Client?.Connected == true)
if (_client?.Connected == true)
{
Close();
}
Listener = new TcpListener(IPAddress.Any, 0);
Listener.Start();
_listener = new TcpListener(IPAddress.Any, 0);
_listener.Start();
}
public void AcceptClient(bool authenticateAfter = false)
public void AcceptClient()
{
_acceptTask = Listener.AcceptTcpClientAsync().ContinueWith(t =>
_acceptTask = _listener.AcceptTcpClientAsync().ContinueWith(t =>
{
Client = t.Result;
_client = t.Result;
if (IsTslProtected)
{
var sslStream = new SslStream(Client.GetStream(), false);
var sslStream = new SslStream(_client.GetStream(), false);
sslStream.AuthenticateAsServer(FtpServer.Instance.Configuration.Tls.X509Certificate, false, true);
Stream = sslStream;
}
else
{
Stream = Client.GetStream();
Stream = _client.GetStream();
}
});
}
public void ActivateTsl()
public void ActivateTls()
{
IsTslProtected = true;
}
public void DesactivateTsl()
public void DesactivateTls()
{
IsTslProtected = false;
}
@@ -93,8 +94,8 @@ namespace DearFTP.Connection
public void Close()
{
Stream.Close();
Client.Close();
Listener.Stop();
_client.Close();
_listener.Stop();
}
}
}

View File

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace DearFTP.Connection
{
interface IDataConnection
{
Stream Stream { get; }
int Port { get; }
bool IsTslProtected { get; }
bool IsAvailable { get; }
void Create();
void AcceptClient();
void ActivateTls();
void DesactivateTls();
void Close();
}
}

View File

@@ -22,7 +22,7 @@ namespace DearFTP.Connection
public Share[] WritablesShares { get; set; }
public NavigablePath NavigablePath { get; set; }
public FtpStream FtpStream { get; private set; }
public DataConnection DataConnection { get; set; }
public IDataConnection DataConnection { get; set; }
public int RestartPosition { get; set; }
public bool IsTlsProtected { get; private set; }
public string CurrentWorkingDirectory => NavigablePath.CurrentDirectory;
@@ -43,7 +43,7 @@ namespace DearFTP.Connection
Configuration = FtpServer.Instance.Configuration;
CommandsDispatcher = FtpServer.Instance.CommandsDispatcher;
Logger = FtpServer.Instance.Logger;
DataConnection = new DataConnection();
DataConnection = Configuration.Server.ForceDataPort == 0 ? (IDataConnection)new DynamicDataConnection() : new StaticDataConnection();
RestartPosition = 0;
IsTlsProtected = false;
}
@@ -94,6 +94,7 @@ namespace DearFTP.Connection
_sslStream?.Close();
_networkStream.Close();
_client.Close();
DataConnection.Close();
}
}
}

View File

@@ -0,0 +1,108 @@
using System;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace DearFTP.Connection
{
class StaticDataConnection : IDataConnection
{
public const int Timeout = 10_000;
public Stream Stream { get; private set; }
public bool IsTslProtected { get; private set; }
public int Port => ((IPEndPoint)_listener.LocalEndpoint).Port;
public bool IsAvailable
{
get
{
if (_acceptTask == null)
{
return false;
}
else if (_acceptTask.Wait(Timeout))
{
return true;
}
else
{
_acceptTask.Dispose();
_acceptTask = null;
return false;
}
}
}
private static TcpListener _listener;
private static Task _acceptTask;
private TcpClient _client;
public StaticDataConnection()
{
if (_listener == null)
{
_listener = new TcpListener(IPAddress.Any, FtpServer.Instance.Configuration.Server.ForceDataPort);
_listener.Start();
}
IsTslProtected = false;
}
public void AcceptClient()
{
if (_acceptTask?.IsCompleted == false)
{
_acceptTask.Wait(Timeout);
_acceptTask.Dispose();
_acceptTask = null;
}
_acceptTask = _listener.AcceptTcpClientAsync().ContinueWith(t =>
{
_client = t.Result;
if (IsTslProtected)
{
var sslStream = new SslStream(_client.GetStream(), false);
sslStream.AuthenticateAsServer(FtpServer.Instance.Configuration.Tls.X509Certificate, false, true);
Stream = sslStream;
}
else
{
Stream = _client.GetStream();
}
});
}
public void ActivateTls()
{
IsTslProtected = true;
}
public void Close()
{
Stream.Close();
_client.Close();
}
public void Create()
{
// Nothing to create as the TcpListener is shared by all
}
public void DesactivateTls()
{
IsTslProtected = false;
}
public static void Stop()
{
_listener?.Stop();
}
}
}

View File

@@ -46,6 +46,7 @@ namespace DearFTP
{
_isRunning = false;
_listener.Stop();
StaticDataConnection.Stop();
}
private void TcpLoop()