-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add TryLogin(string, SecureString) methods
This commit does all the following - Add TryLogin(string, SecureString) methods so that the password can be passed as a SecureString - Added credential manager classes for Linux, macOS and Windows - macOS: KeyChain - Linux: libsecret (depends on libsecret-tools cli) - Windows: Credential Manager - Create dotnet tool `metasys-secrets` which is cross platform and can be used on macOS, Linux and Windows to add credentials to the default credential manager - Added steps in CI build to test on Windows and macOS as well
- Loading branch information
1 parent
3d2c305
commit 54016ea
Showing
20 changed files
with
1,395 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
nupkg/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\MetasysServices\MetasysServices.csproj" /> | ||
<None Include="./README.md" Pack="true" PackagePath="/" /> | ||
</ItemGroup> | ||
|
||
<PropertyGroup> | ||
<PackageId>JohnsonControls.MetasysSecrets</PackageId> | ||
<Version>1.0.0-alpha2</Version> | ||
<Authors>Johnson Controls PLC</Authors> | ||
<Description>A cross platform cli tool for adding Metasys passwords to your operating system credential manager</Description> | ||
<PackageTags>secrets;secret;cli;metasys</PackageTags> | ||
<PackageReleaseNotes>Initial Release for macOS, Linux and Windows. The Linux version has a dependency on libsecret-tools</PackageReleaseNotes> | ||
<RepositoryUrl>https://github.com/jci-metasys/basic-services-dotnet/tree/master/MetasysSecrets/</RepositoryUrl> | ||
<RepositoryType>git</RepositoryType> | ||
<PackageLicenseExpression>BSD-3-Clause</PackageLicenseExpression> | ||
<PackageReadmeFile>README.md</PackageReadmeFile> | ||
<OutputType>Exe</OutputType> | ||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<PackAsTool>true</PackAsTool> | ||
<ToolCommandName>metasys-secrets</ToolCommandName> | ||
<PackageOutputPath>./nupkg</PackageOutputPath> | ||
</PropertyGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// See https://aka.ms/new-console-template for more information | ||
using System.Runtime.InteropServices; | ||
using System.Security; | ||
using JohnsonControls.Metasys.BasicServices; | ||
|
||
if (args.Length != 3 || !(args[0] is "add" or "lookup" or "delete")) | ||
{ | ||
WriteUsage(); | ||
return; | ||
} | ||
|
||
|
||
switch (args[0]) | ||
{ | ||
case "add": | ||
var password = GetPassword(); | ||
SecretStore.AddOrReplacePassword(args[1], args[2], password); | ||
break; | ||
case "lookup": | ||
if (SecretStore.TryGetPassword(args[1], args[2], out SecureString securePassword)) | ||
{ | ||
Console.WriteLine(ConvertToPlainText(securePassword)); | ||
} | ||
break; | ||
case "delete": | ||
SecretStore.DeletePassword(args[1], args[2]); | ||
break; | ||
default: | ||
break; | ||
} | ||
|
||
string ConvertToPlainText(SecureString secureString) | ||
{ | ||
IntPtr unmanagedString = IntPtr.Zero; | ||
try | ||
{ | ||
unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString); | ||
return Marshal.PtrToStringUni(unmanagedString) ?? ""; | ||
} | ||
finally | ||
{ | ||
Marshal.ZeroFreeGlobalAllocUnicode(unmanagedString); | ||
} | ||
} | ||
|
||
void WriteUsage() | ||
{ | ||
Console.WriteLine("Usage:"); | ||
Console.WriteLine(" metasys-secret add {host} {username}"); | ||
Console.WriteLine(" metasys-secret lookup {host} {username}"); | ||
Console.WriteLine(" metasys-secret delete {host} {username}"); | ||
return; | ||
} | ||
|
||
SecureString GetPassword() | ||
{ | ||
SecureString password = new SecureString(); | ||
if (Console.IsInputRedirected) | ||
{ | ||
var input = Console.ReadLine(); | ||
input?.ToCharArray().ToList().ForEach(password.AppendChar); | ||
return password; | ||
} | ||
Console.Write("Enter your password: "); | ||
|
||
while (true) | ||
{ | ||
|
||
ConsoleKeyInfo key = Console.ReadKey(intercept: true); | ||
if (key.Key == ConsoleKey.Enter) | ||
{ | ||
break; | ||
} | ||
else if (key.Key == ConsoleKey.Backspace) | ||
{ | ||
if (password.Length > 0) | ||
{ | ||
password.RemoveAt(password.Length - 1); | ||
// backup, write a space, and back up again | ||
Console.Write("\b \b"); | ||
} | ||
} | ||
else | ||
{ | ||
password.AppendChar(key.KeyChar); | ||
Console.Write("*"); | ||
} | ||
} | ||
Console.WriteLine(); | ||
password.MakeReadOnly(); | ||
return password; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# Metasys Secrets | ||
|
||
A cli for adding metasys passwords to your operating system credential manager. | ||
These credentials can then be retrieved by your applications using | ||
[SecretStore](../MetasysServices/Credentials/Secrets.cs) and the password can be | ||
securely passed to `MetasysClient.TryLogin` method of | ||
[basic-services-dotnet](../README.md). | ||
|
||
## Installation | ||
|
||
You'll need a modern version of | ||
[dotnet](https://dotnet.microsoft.com/en-us/download). Both .Net 6.0 and .Net | ||
8.0 are supported. | ||
|
||
```bash | ||
dotnet tool install --global JohnsonControls.MetasysSecrets | ||
``` | ||
|
||
## Usage | ||
|
||
There are three subcommands `add`, `lookup` and `delete` as shown below. Each | ||
takes a `hostName` and `userName` for arguments. | ||
|
||
```bash | ||
metasys-secrets add <hostName> <userName> | ||
metasys-secrets lookup <hostName> <userName> | ||
metasys-secrets delete <hostName> <userName> | ||
``` | ||
|
||
### Examples | ||
|
||
In these examples we'll assume that the `hostName` is | ||
`my-ads-server.company.com` and the `userName` is `api-service-account`. | ||
|
||
### Save a Password | ||
|
||
To save the password | ||
|
||
```bash | ||
> metasys-secrets add my-ads-server.company.com api-service-account | ||
Enter your password: ******* | ||
``` | ||
|
||
Notice you are prompted for your password. If you really want to do it all on | ||
one line you can do it like this. | ||
|
||
```bash | ||
echo "thepassword" | metasys-secrets add my-ads-server.company.com api-service-account | ||
``` | ||
|
||
> [!Warning]\ | ||
> Be careful with this approach as your password is now shown in plain text and will | ||
> be stored in your shell history. It's not recommended for production environments. | ||
### Delete a Password | ||
|
||
To delete a password from your credential manager you can do | ||
|
||
```bash | ||
metasys-secrets delete <hostName> <userName> | ||
``` | ||
|
||
### Display a Password | ||
|
||
To read a password from the credential manager you can do | ||
|
||
```bash | ||
metasys-secrets lookup <hostName> <userName> | ||
``` | ||
|
||
> [!Warning]\ | ||
> Be careful with this approach as your password is now shown in plain text.It's | ||
> not recommended for production environments. You may choose to use the GUI tool | ||
> for your operating system instead. | ||
## Credential Managers | ||
|
||
The credential manager that is used depends on the operating system you are | ||
using. | ||
|
||
### Windows | ||
|
||
On Windows the passwords are saved in the Windows Credential Manager. | ||
|
||
### macOS | ||
|
||
On macOS the passwords are saved in the macOS Keychain | ||
|
||
### Linux | ||
|
||
On Linux the passwords are saved using `libsecret` and it relies on the linux | ||
command line tool `secret-tool`. To install that tool depends on the | ||
distribution you are using. | ||
|
||
On Debian/Ubuntu you can install it like this | ||
|
||
```bash | ||
sudo apt install libsecret-tools | ||
``` |
Oops, something went wrong.