69 lines
2.8 KiB
C#
69 lines
2.8 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace Microsoft.AspNetCore.Razor.Tools
|
|
{
|
|
internal static class PipeName
|
|
{
|
|
// We want each pipe to unique and predictable based on the inputs of:
|
|
// - user (security)
|
|
// - elevation status (security)
|
|
// - path of tool on disk (version)
|
|
//
|
|
// This allows us to meet the security and version compat requirements just by selecting a pipe name.
|
|
//
|
|
// https://github.com/dotnet/corefx/issues/25427 will actually enforce the security, but we still
|
|
// want these guarantees when we try to connect so we can expect it to succeed.
|
|
//
|
|
// This is similar to (and based on) the code used by Roslyn in VBCSCompiler:
|
|
// https://github.com/dotnet/roslyn/blob/c273b6a9f19570a344c274ae89185b3a2b64d93d/src/Compilers/Shared/BuildServerConnection.cs#L528
|
|
public static string ComputeDefault()
|
|
{
|
|
// Include a prefix so we can't conflict with VBCSCompiler if we somehow end up in the same directory.
|
|
// That would be a pretty wacky bug to try and unravel.
|
|
var baseName = ComputeBaseName("Razor:" + AppDomain.CurrentDomain.BaseDirectory);
|
|
|
|
// Prefix with username and elevation
|
|
bool isAdmin = false;
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
{
|
|
#if WINDOWS_HACK_LOL
|
|
var currentIdentity = WindowsIdentity.GetCurrent();
|
|
var principal = new WindowsPrincipal(currentIdentity);
|
|
isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
|
|
#endif
|
|
}
|
|
|
|
var userName = Environment.UserName;
|
|
if (userName == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
return $"{userName}.{(isAdmin ? 'T' : 'F')}.{baseName}";
|
|
}
|
|
|
|
private static string ComputeBaseName(string baseDirectory)
|
|
{
|
|
// Normalize away trailing slashes. File APIs are not consistent about including it, so it's
|
|
// best to normalize and avoid ending up with two servers running accidentally.
|
|
baseDirectory = baseDirectory.TrimEnd(Path.DirectorySeparatorChar);
|
|
|
|
using (var sha = SHA256.Create())
|
|
{
|
|
var bytes = sha.ComputeHash(Encoding.UTF8.GetBytes(baseDirectory));
|
|
return Convert.ToBase64String(bytes)
|
|
.Substring(0, 25) // We only have ~50 total characters on Mac, so strip that down
|
|
.Replace("/", "_")
|
|
.Replace("=", string.Empty);
|
|
}
|
|
}
|
|
}
|
|
}
|