Add ForceDataPort configuration
Use StaticDataConnection
This commit is contained in:
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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%";
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
21
DearFTP/Connection/IDataConnection.cs
Normal file
21
DearFTP/Connection/IDataConnection.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
108
DearFTP/Connection/StaticDataConnection.cs
Normal file
108
DearFTP/Connection/StaticDataConnection.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ namespace DearFTP
|
||||
{
|
||||
_isRunning = false;
|
||||
_listener.Stop();
|
||||
StaticDataConnection.Stop();
|
||||
}
|
||||
|
||||
private void TcpLoop()
|
||||
|
||||
Reference in New Issue
Block a user