0 votes
by (150 points)
edited by

I've implemented a custom file system to use with Rebex FileServer as an SFTP server. During authentication I create a FileServerUser with a custom session context:

var user = new FileServerUser(e.UserName, null, sftpFileSystem, virtualDirectory);
e.Accept(user, new SftpSessionContext { RequestId = Activity.Current.Id });

According to the documentation the ServerSession.Current should be available within the methods of the custom file system, but during the login process, it seems that the Exists method is called before ServerSession.Current is initialized:

protected override bool Exists(NodePath path, NodeType nodeType)
{
    logger
        .Trace($"SFTP Server: {nameof(Exists)}({path.StringPath})")
        .WithRequestId((ServerSession.Current.Context as SftpSessionContext).RequestId) 
        .Log();
    [...]
}

Calling ServiceSession.Current.Context throws a NullReferenceException and the client shows an authentication failed error.

Is this the excepted behavior within Exists during authentication?

Regards,

Kay Zumbusch

Applies to: Rebex SFTP

1 Answer

0 votes
by (149k points)
selected ago by
 
Best answer

This is actually a somewhat peculiar case, thanks for bringing it to our attention.

This particular Exists call was not made via the server, but rather from the FileServerUser constructor:

new FileServerUser(e.UserName, null, sftpFileSystem, virtualDirectory);

Purpose of the Exists call is to check whether the virtualDirectory actually exists, to prevent the server from failing later when SFTP protocol is getting initialized.

However, the FileServerUser constructor is not aware of the context because it has not been set yet, so that single Exists call can't really behave as documented. So, indeed, it's an expected (but undocumented) behavior.

I'm not quite sure how to best address this (apart from updating the documentation). But there is a workaround involving an undocumented SkipVirtualRootPathCheck option that disables the Exists call. Instead of your FileServerUser constructor call, use this:

var user = new FileServerUser(e.UserName, null);
Rebex.Security.Cryptography.CryptoHelper.SetOption(user, "SkipVirtualRootPathCheck", true);
user.SetFileSystem(sftpFileSystem, virtualDirectory);

This option was added to address another problem, but it's apparently useful here as well.

...