Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
112 lines (98 loc) · 4 KB

File metadata and controls

112 lines (98 loc) · 4 KB
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
namespace Npgsql;
/// <summary>
/// Launches MIT Kerberos klist and parses out the default principal from it.
/// Caches the result.
/// </summary>
static class KerberosUsernameProvider
{
static volatile bool _performedDetection;
static string? _principalWithRealm;
static string? _principalWithoutRealm;
internal static ValueTask<string?> GetUsername(bool async, bool includeRealm, ILogger connectionLogger, CancellationToken cancellationToken)
{
if (_performedDetection)
return new(includeRealm ? _principalWithRealm : _principalWithoutRealm);
var klistPath = FindInPath("klist");
if (klistPath == null)
{
connectionLogger.LogDebug("klist not found in PATH, skipping Kerberos username detection");
return new((string?)null);
}
var processStartInfo = new ProcessStartInfo
{
FileName = klistPath,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
var process = Process.Start(processStartInfo);
if (process is null)
{
connectionLogger.LogDebug("klist process could not be started");
return new((string?)null);
}
return GetUsernameAsyncInternal();
async ValueTask<string?> GetUsernameAsyncInternal()
{
if (async)
await process.WaitForExitAsync(cancellationToken).ConfigureAwait(false);
else
// ReSharper disable once MethodHasAsyncOverloadWithCancellation
process.WaitForExit();
if (process.ExitCode != 0)
{
connectionLogger.LogDebug($"klist exited with code {process.ExitCode}: {process.StandardError.ReadToEnd()}");
return null;
}
var line = default(string);
for (var i = 0; i < 2; i++)
// ReSharper disable once MethodHasAsyncOverload
if ((line = async ? await process.StandardOutput.ReadLineAsync(cancellationToken).ConfigureAwait(false) : process.StandardOutput.ReadLine()) == null)
{
connectionLogger.LogDebug("Unexpected output from klist, aborting Kerberos username detection");
return null;
}
return ParseKListOutput(line!, includeRealm, connectionLogger);
}
}
static string? ParseKListOutput(string line, bool includeRealm, ILogger connectionLogger)
{
var colonIndex = line.IndexOf(':');
var colonLastIndex = line.LastIndexOf(':');
if (colonIndex == -1 || colonIndex != colonLastIndex)
{
connectionLogger.LogDebug("Unexpected output from klist, aborting Kerberos username detection");
return null;
}
var secondPart = line.AsSpan(1 + line.IndexOf(':'));
var principalWithRealm = secondPart.Trim();
var atIndex = principalWithRealm.IndexOf('@');
var atLastIndex = principalWithRealm.LastIndexOf('@');
if (atIndex == -1 || atIndex != atLastIndex)
{
connectionLogger.LogDebug(
$"Badly-formed default principal {principalWithRealm.ToString()} from klist, aborting Kerberos username detection");
return null;
}
_principalWithRealm = principalWithRealm.ToString();
_principalWithoutRealm = principalWithRealm.Slice(0, atIndex).ToString();
_performedDetection = true;
return includeRealm ? _principalWithRealm : _principalWithoutRealm;
}
static string? FindInPath(string name)
{
foreach (var p in Environment.GetEnvironmentVariable("PATH")?.Split(Path.PathSeparator) ?? [])
{
var path = Path.Combine(p, name);
if (File.Exists(path))
return path;
}
return null;
}
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.