Skip to content

Commit

Permalink
Added support of username
Browse files Browse the repository at this point in the history
  • Loading branch information
sakno committed Jan 13, 2024
1 parent abde7c5 commit 81e2b60
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,7 @@ private static IIdentity GetRemotePeerIdentity(Socket socket)
{
if (OperatingSystem.IsLinux() && socket.TryGetCredentials(out var processId, out var userId, out var groupId))
{
return new LinuxUdsPeerIdentity()
{
ProcessId = processId,
UserId = userId,
GroupId = groupId,
};
return new LinuxUdsPeerIdentity(processId, userId, groupId);
}

return AnonymousPrincipal.Instance;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Runtime.Versioning;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

namespace DotNext.Security.Principal;

Expand All @@ -12,11 +14,35 @@ namespace DotNext.Security.Principal;
[CLSCompliant(false)]
public sealed record class LinuxUdsPeerIdentity : IIdentity
{
private static readonly Getpwuid? GetpwuidFunction;

static LinuxUdsPeerIdentity()
{
var getpwuid = NativeLibrary.GetExport(NativeLibrary.GetMainProgramHandle(), "getpwuid");
GetpwuidFunction = getpwuid is not 0
? Marshal.GetDelegateForFunctionPointer<Getpwuid>(getpwuid)
: null;
}

[SupportedOSPlatform("linux")]
internal LinuxUdsPeerIdentity()
internal LinuxUdsPeerIdentity(uint pid, uint uid, uint gid)
{
if (!OperatingSystem.IsLinux())
throw new PlatformNotSupportedException();

ProcessId = pid;
UserId = uid;
GroupId = gid;

if (GetpwuidFunction is not null)
{
ref var passwd = ref GetpwuidFunction(uid);
if (!Unsafe.IsNullRef(ref passwd))
{
Name = Marshal.PtrToStringAnsi(passwd.Name);
DisplayName = Marshal.PtrToStringAnsi(passwd.UserInfo);
}
}
}

/// <summary>
Expand All @@ -27,21 +53,41 @@ internal LinuxUdsPeerIdentity()
/// <summary>
/// Gets calling process ID.
/// </summary>
public uint ProcessId { get; internal init; }
public uint ProcessId { get; }

/// <summary>
/// Gets user ID of the process identified by <see cref="ProcessId"/>.
/// </summary>
public uint UserId { get; internal init; }
public uint UserId { get; }

/// <summary>
/// Gets group ID of the process identified by <see cref="ProcessId"/>.
/// </summary>
public uint GroupId { get; internal init; }
public uint GroupId { get; }

/// <inheritdoc />
string? IIdentity.AuthenticationType => "ucred";

/// <inheritdoc />
string? IIdentity.Name => null;
public string? Name { get; }

/// <summary>
/// Gets user information, if available.
/// </summary>
public string? DisplayName { get; }

[StructLayout(LayoutKind.Sequential)]
private readonly struct Passwd
{
internal readonly nint Name;
internal readonly nint Password;
internal readonly uint UserId;
internal readonly uint GroupId;
internal readonly nint UserInfo;
internal readonly nint HomeDirectory;
internal readonly nint Shell;
}

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate ref Passwd Getpwuid(uint userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static async Task DefaultCommandsAsync(string request, string response)
await host.StopAsync();
}

[PlatformSpecificFact("linux")]
[Fact]
public static async Task UdsEndpointAuthentication()
{
var unixDomainSocketPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
Expand All @@ -71,8 +71,9 @@ public static async Task UdsEndpointAuthentication()
command.SetHandler(static session =>
{
True(session.Identity.IsAuthenticated);
IsType<LinuxUdsPeerIdentity>(session.Identity);
session.ResponseWriter.Write(((LinuxUdsPeerIdentity)session.Identity).ProcessId);
var identity = IsType<LinuxUdsPeerIdentity>(session.Identity);
Equal(Environment.UserName, identity.Name);
session.ResponseWriter.Write(identity.ProcessId);
},
DefaultBindings.Session);
});
Expand Down

0 comments on commit 81e2b60

Please sign in to comment.