Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identify which user is connected #7

Closed
AtleC opened this issue Nov 25, 2021 · 8 comments
Closed

Identify which user is connected #7

AtleC opened this issue Nov 25, 2021 · 8 comments
Labels
enhancement New feature or request

Comments

@AtleC
Copy link

AtleC commented Nov 25, 2021

Hi,

In System.IO.Pipes there is a function "GetImpersonationUserName()" for getting the username of the user connecting.
Have you looked into adding similar capabilities?

This would need to be handled server side to avoid the possibility of a user impersonating another user.

@HavenDV HavenDV added the enhancement New feature or request label Nov 25, 2021
@HavenDV
Copy link
Owner

HavenDV commented Nov 25, 2021

Added in the latest release. Usage:

server.ClientConnected += async (o, args) =>
{
    var name = args.Connection.GetImpersonationUserName();

    Console.WriteLine($"Client {name} is now connected!");
};

@AtleC
Copy link
Author

AtleC commented Nov 25, 2021

Nice!

It seems like there is an issue with the latest versions (1.15.7 and 1.15.8) in nuget tho:
image

I get this when trying to debug in Visual studio 2022, with 1.15.6 it works

@HavenDV
Copy link
Owner

HavenDV commented Nov 25, 2021

Yes, I forgot to release new versions of Formatter packages after refactoring. Should be fixed in the latest version.

@AtleC
Copy link
Author

AtleC commented Nov 25, 2021

Awesome, that worked 👍

Looking further into it, there also seems like there is a way to get the PID of the client process

`[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool GetNamedPipeClientProcessId(IntPtr Pipe, out int ClientProcessId);

int GetNamedPipeClientProcessId(NamedPipeServerStream pipeServer)
{
var hPipe = pipeServer.SafePipeHandle.DangerousGetHandle();

if (GetNamedPipeClientProcessId(hPipe, out var clientProcessId))
{
    return clientProcessId;
}
else
{
    var error = Marshal.GetLastWin32Error();
    return 0;
}

}`

This works great if called straight from the NamedPipeServerStream, but this is not exposed in H.Pipes.

Could this also be implemented?
I took a stab at it myself but have not yet found a way to import GetNamedPipeClientProcessId into H.Pipes.
A possible solution could be to pass the NamedPipeServerStream into ConnectionEventArgs, but I guess that would be less than optimal.

@HavenDV
Copy link
Owner

HavenDV commented Nov 25, 2021

I have moved PipeConnection.PipeStream to public properties for advanced use.

/// <summary>
/// Raw pipe stream. You can cast it to <see cref="NamedPipeClientStream"/> or <see cref="NamedPipeServerStream"/>.
/// </summary>
public PipeStream PipeStream { get; }

@AtleC
Copy link
Author

AtleC commented Nov 25, 2021

I found a way 🤡

I'm not quite sure were to place the dll reference, I did a temporary placement in EventExtensions.cs
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetNamedPipeClientProcessId(IntPtr Pipe, out int ClientProcessId);
and then just place this in PipeConnection.cs
` ///


/// Gets the process PID of the client on the other end of the pipe.
///

/// The process PID of the client on the other end of the pipe.
/// is not .
/// No pipe connections have been made yet.
/// The connected pipe has already disconnected.
/// The pipe handle has not been set.
/// The pipe is closed.
/// The pipe connection has been broken.
/// The process PID of the client is longer than 19 characters.
public int GetNamedPipeClientProcessId()
{
if (PipeStream is not NamedPipeServerStream serverStream)
{
throw new InvalidOperationException($"{nameof(PipeStream)} is not {nameof(NamedPipeServerStream)}.");
}

    var hPipe = PipeStream.SafePipeHandle.DangerousGetHandle();

    if (EventExtensions.GetNamedPipeClientProcessId(hPipe, out var clientProcessId))
    {
        return clientProcessId;
    }
    else
    {
        var error = Marshal.GetLastWin32Error();
        return 0;
    }
}

`

We can then call it the same way as GetImpersonationUserName

var test = args.Connection.GetNamedPipeClientProcessId();

@HavenDV
Copy link
Owner

HavenDV commented Nov 25, 2021

I am guessing that you can just add an Extension method for the PipeConnection.
I don't want to add Win32 API calls to the library at the moment.

@AtleC
Copy link
Author

AtleC commented Nov 25, 2021

Absolutely, thanks for all the help.
H.Pipes looks like a promising project 👍

@HavenDV HavenDV closed this as completed Nov 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants