Update: This approach is no longer necessary. See the new answer for a simple solution available since Rebex File Server 2017 R4.
IP address is not available in FileUploaded
/FileDownloaded
events (yet), but you can work around this by using a custom user class and a custom Authentication
event that associates an IP with a per-session user object.
Try using this custom user class:
public class CustomUser : FileServerUser
{
private readonly string _userName;
private readonly string _password;
private readonly string _virtualRootPath;
public CustomUser(string userName, string password, string virtualRootPath)
: base(userName, password, virtualRootPath)
{
_userName = userName;
_password = password;
_virtualRootPath = virtualRootPath;
}
private class ActiveCustomUser : CustomUser
{
public IPAddress Address { get; private set; }
public ActiveCustomUser(IPAddress address, string userName, string password, string virtualRootPath)
: base(userName, password, virtualRootPath)
{
Address = address;
}
}
public FileServerUser ToActiveUser(IPAddress address)
{
return new ActiveCustomUser(address, _userName, _password, _virtualRootPath);
}
public static IPAddress GetAddress(FileServerUser user)
{
var activeUser = user as ActiveCustomUser;
if (activeUser == null)
return IPAddress.None;
else
return activeUser.Address;
}
}
To make it work, you have to provide Authentication
and FileUploaded
/FileDownloaded
events:
var server = new FileServer();
server.Keys.Add(...);
server.Bind(22, FileServerProtocol.Sftp);
server.Users.Add(new CustomUser("user01", "password", @"c:\temp\SftpRoot"));
server.Authentication += (sender, e) =>
{
var user = (CustomUser)e.Users[e.UserName];
if (user.CheckPassword(e.Password))
{
e.Accept(user.ToActiveUser(e.ClientAddress));
return;
}
e.Reject();
};
server.FileUploaded += (sender, e) =>
{
IPAddress address = CustomUser.GetAddress(e.User);
...
};
server.Start();
Rejecting access from unwanted IP addresses is possible in Connecting
event:
server.Connecting += (sender, e) =>
{
e.Accept = IsAllowed(e.ClientAddress);
};
This will still accept the incoming connection, but it will be closed immediately without performing any SSH negotiation. If you prefer rejecting the connection attempts without accepting them first, you would have to do that at the firewall.