Security Considerations

During interprocess communications, the RPC server does not enforce security at a network level. This means that the "server" can serve any RPC client that connects to this endpoint; the user credentials of the "server" may be different from the user credentials of the "client".

Client Identity

The .NET CBFS Shell RPC server always provides the client user identity through the ClientPrincipalName string property of the CBFS Shell-provided ShellContext class.

CBFS Shell also provides an impersonation feature that allows the .NET server to behave as the connecting client. This feature is enabled by default. It can be turned off, however, using the following startup code (config is of the ShellConfiguration type):

using (var server = new MyShellFolderServer())
    var config = new ShellFolderConfiguration();
    config.ImpersonateClient = false;

Thanks to impersonation turned on by default, the result of calling Environment.UserName or WindowsIdentity.GetCurrent() standard .NET methods should return the same value as ShellContext.Current.ClientPrincipalName, even if the client process is calling from a different desktop/session than the server process. If you turn impersonation off, however, you must rely only on ShellContext.Current.ClientPrincipalName to determine the client user identity.

Note: Independent from security issues, custom UI (e.g., dialog box, windows, windows messages) is not supported when a server and a client run in different desktop sessions.

CBFS Shell as a Windows Service

A Windows service is probably going to be running under specific credentials, different from users working with their Windows Shell in their desktop sessions. In this case, a CBFS Shell developer may choose to impersonate the client user (run "as" the user, with the user's credentials), or just identify it. Impersonation is a global setting that, if required, should be set at application start time. By default, CBFS Shell enables client impersonation.

Even with impersonation disabled, a CBFS Shell developer can obtain the client identity and client process identifier using the ShellContext class.

The following extract is taken from the Folder Service sample. The root folder services five items that display diagnostic-type information. The following example is for demonstration purposes:

public class RootFolder : RootShellFolder
    public RootFolder(OverviewShellFolderServer server, ShellItemIdList idList)
        : base(idList)
        Server = server;
    public OverviewShellFolderServer Server { get; }
    public override IEnumerable<ShellItem> EnumItems(SHCONTF options)
        yield return new SimpleItem(this, "Client Principal Name: " + ShellContext.Current.ClientPrincipalName);
        yield return new SimpleItem(this, "Client Process Id: " + ShellContext.Current.ClientProcessId);
        yield return new SimpleItem(this, "Client Process: " + Process.GetProcessById(ShellContext.Current.ClientProcessId)?.ProcessName);
        // if we impersonate, this will be the same as the client principal name
        // otherwise it will be the identity that runs the service process
        yield return new SimpleItem(this, "Server Windows Identity: " + WindowsIdentity.GetCurrent()?.Name);
        yield return new SimpleItem(this, "Server Process: " + Process.GetCurrentProcess().ProcessName);

The service's OnStart() method is implemented as follows:

protected override void OnStart(string[] args)
    _server = new OverviewShellFolderServer();
    var config = new ShellFolderConfiguration();
    config.ImpersonateClient = true; // true is the default
    config.NativeDllRegistration = RegistrationMode.User;

As you can see in the following image, the service is configured to run as "Local System".

The CBFS Shell Namespace Extension appears as follows:

This information is computed from the ShellBoost.Samples.FolderService, running as "Local System". Because the user is impersonated, the service's Windows identity name is the same as the client's principal name. In this case, the client process is Explorer (.exe).

Next, we can change the startup code, as follows (stop the service, recompile, restart the service, refresh Explorer):

config.ImpersonateClient = false;

Then, the CBFS Shell Namespace Extension will appear as follows:

Now, the service's Windows identity is NT AUTHORITY\SYSTEM (which is "Local Service"). The correct client identity, however, is still available.

Note: Custom UI is not supported from Windows services because they cannot interact with desktops.

Copyright (c) 2022 Callback Technologies, Inc. - All rights reserved.
CBFS Shell 2022 .NET Edition - Version 22.0 [Build 8172]