Add ForceDataPort configuration
Use StaticDataConnection
This commit is contained in:
@@ -108,7 +108,7 @@ namespace DearFTP.Configurations
|
|||||||
|
|
||||||
public void Save()
|
public void Save()
|
||||||
{
|
{
|
||||||
var serializer = new SerializerBuilder().EmitDefaults().Build();
|
var serializer = new SerializerBuilder().Build();
|
||||||
|
|
||||||
File.WriteAllText(ConfigurationPath, serializer.Serialize(this));
|
File.WriteAllText(ConfigurationPath, serializer.Serialize(this));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace DearFTP.Configurations
|
|||||||
class ServerConfiguration
|
class ServerConfiguration
|
||||||
{
|
{
|
||||||
public ushort Port { get; set; } = 21;
|
public ushort Port { get; set; } = 21;
|
||||||
|
public ushort ForceDataPort { get; set; } = 0;
|
||||||
public string MOTD { get; set; } = "DearFTP v0.1";
|
public string MOTD { get; set; } = "DearFTP v0.1";
|
||||||
public string LoginMessage { get; set; } = "Logged in as %user%";
|
public string LoginMessage { get; set; } = "Logged in as %user%";
|
||||||
|
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ namespace DearFTP.Connection.Commands
|
|||||||
switch (argument.ToUpper())
|
switch (argument.ToUpper())
|
||||||
{
|
{
|
||||||
case "C":
|
case "C":
|
||||||
session.DataConnection.DesactivateTsl();
|
session.DataConnection.DesactivateTls();
|
||||||
stream.Send(ResponseCode.OK, "Data protection cleared.");
|
stream.Send(ResponseCode.OK, "Data protection cleared.");
|
||||||
break;
|
break;
|
||||||
case "P":
|
case "P":
|
||||||
session.DataConnection.ActivateTsl();
|
session.DataConnection.ActivateTls();
|
||||||
stream.Send(ResponseCode.OK, "Data protection set.");
|
stream.Send(ResponseCode.OK, "Data protection set.");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -11,15 +11,14 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace DearFTP.Connection
|
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 Stream Stream { get; private set; }
|
||||||
public bool IsTslProtected { 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
|
public bool IsAvailable
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@@ -41,9 +40,11 @@ namespace DearFTP.Connection
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TcpListener _listener;
|
||||||
|
private TcpClient _client;
|
||||||
private Task _acceptTask;
|
private Task _acceptTask;
|
||||||
|
|
||||||
public DataConnection()
|
public DynamicDataConnection()
|
||||||
{
|
{
|
||||||
IsTslProtected = false;
|
IsTslProtected = false;
|
||||||
}
|
}
|
||||||
@@ -51,41 +52,41 @@ namespace DearFTP.Connection
|
|||||||
public void Create()
|
public void Create()
|
||||||
{
|
{
|
||||||
// Clean old connections
|
// Clean old connections
|
||||||
if (Client?.Connected == true)
|
if (_client?.Connected == true)
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Listener = new TcpListener(IPAddress.Any, 0);
|
_listener = new TcpListener(IPAddress.Any, 0);
|
||||||
Listener.Start();
|
_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)
|
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);
|
sslStream.AuthenticateAsServer(FtpServer.Instance.Configuration.Tls.X509Certificate, false, true);
|
||||||
|
|
||||||
Stream = sslStream;
|
Stream = sslStream;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Stream = Client.GetStream();
|
Stream = _client.GetStream();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ActivateTsl()
|
public void ActivateTls()
|
||||||
{
|
{
|
||||||
IsTslProtected = true;
|
IsTslProtected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DesactivateTsl()
|
public void DesactivateTls()
|
||||||
{
|
{
|
||||||
IsTslProtected = false;
|
IsTslProtected = false;
|
||||||
}
|
}
|
||||||
@@ -93,8 +94,8 @@ namespace DearFTP.Connection
|
|||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
Stream.Close();
|
Stream.Close();
|
||||||
Client.Close();
|
_client.Close();
|
||||||
Listener.Stop();
|
_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 Share[] WritablesShares { get; set; }
|
||||||
public NavigablePath NavigablePath { get; set; }
|
public NavigablePath NavigablePath { get; set; }
|
||||||
public FtpStream FtpStream { get; private set; }
|
public FtpStream FtpStream { get; private set; }
|
||||||
public DataConnection DataConnection { get; set; }
|
public IDataConnection DataConnection { get; set; }
|
||||||
public int RestartPosition { get; set; }
|
public int RestartPosition { get; set; }
|
||||||
public bool IsTlsProtected { get; private set; }
|
public bool IsTlsProtected { get; private set; }
|
||||||
public string CurrentWorkingDirectory => NavigablePath.CurrentDirectory;
|
public string CurrentWorkingDirectory => NavigablePath.CurrentDirectory;
|
||||||
@@ -43,7 +43,7 @@ namespace DearFTP.Connection
|
|||||||
Configuration = FtpServer.Instance.Configuration;
|
Configuration = FtpServer.Instance.Configuration;
|
||||||
CommandsDispatcher = FtpServer.Instance.CommandsDispatcher;
|
CommandsDispatcher = FtpServer.Instance.CommandsDispatcher;
|
||||||
Logger = FtpServer.Instance.Logger;
|
Logger = FtpServer.Instance.Logger;
|
||||||
DataConnection = new DataConnection();
|
DataConnection = Configuration.Server.ForceDataPort == 0 ? (IDataConnection)new DynamicDataConnection() : new StaticDataConnection();
|
||||||
RestartPosition = 0;
|
RestartPosition = 0;
|
||||||
IsTlsProtected = false;
|
IsTlsProtected = false;
|
||||||
}
|
}
|
||||||
@@ -94,6 +94,7 @@ namespace DearFTP.Connection
|
|||||||
_sslStream?.Close();
|
_sslStream?.Close();
|
||||||
_networkStream.Close();
|
_networkStream.Close();
|
||||||
_client.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;
|
_isRunning = false;
|
||||||
_listener.Stop();
|
_listener.Stop();
|
||||||
|
StaticDataConnection.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TcpLoop()
|
private void TcpLoop()
|
||||||
|
|||||||
Reference in New Issue
Block a user