Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
v1.0.0
- Initial Version
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

<p align="center">
<!-- Badges -->
<img src="https://img.shields.io/badge/integration_status-prototype-3D1973?style=flat-square" alt="Integration Status: prototype" />
<a href="https://github.com/Keyfactor/password-manager-pro/releases"><img src="https://img.shields.io/github/v/release/Keyfactor/password-manager-pro?style=flat-square" alt="Release" /></a>
<img src="https://img.shields.io/github/issues/Keyfactor/password-manager-pro?style=flat-square" alt="Issues" />
<img src="https://img.shields.io/github/downloads/Keyfactor/password-manager-pro/total?style=flat-square&label=downloads&color=28B905" alt="GitHub Downloads (all assets, all releases)" />
<img src="https://img.shields.io/badge/integration_status-production-3D1973?style=flat-square" alt="Integration Status: production" />
<a href="https://github.com/Keyfactor/password-manager-pro-pam/releases"><img src="https://img.shields.io/github/v/release/Keyfactor/password-manager-pro-pam?style=flat-square" alt="Release" /></a>
<img src="https://img.shields.io/github/issues/Keyfactor/password-manager-pro-pam?style=flat-square" alt="Issues" />
<img src="https://img.shields.io/github/downloads/Keyfactor/password-manager-pro-pam/total?style=flat-square&label=downloads&color=28B905" alt="GitHub Downloads (all assets, all releases)" />
</p>

<p align="center">
Expand Down Expand Up @@ -36,7 +36,8 @@ The Password Manager Pro PAM Provider allows for the retrieval of stored account
## Installation and Configuration

#### In ManageEngine Password Manager Pro
When configuring ManageEngine Password Manager Pro (PMP) for use as a PAM Provider with Keyfactor, you will need to create an API user and generate an API token with the appropriate permissions. Navigate to Users → Add User → Add Api user in the PMP web interface to create the user and token. Ensure the associated user account has at minimum read access to the resources you intend to retrieve credentials from, and the host name field is set to the ip of your KeyFactor Command instance.
When configuring ManageEngine Password Manager Pro (PMP) for use as a PAM Provider with Keyfactor, you will need to create an API user and generate an API token with the appropriate permissions. Navigate to Users → Add User → Add Api user in the PMP web interface to create the user and token. Ensure the associated user account has at minimum read access to the resources you intend to retrieve credentials from, and the host name field is set to the IP of your Keyfactor Command instance.

After ensuring the API User exists and has access to the resource and account you wish to retrieve from PMP, you can use the resource's name (the "Resource Name") and the account name (the "Account Name") to retrieve credentials via the PMP PAM Provider extension.

#### On the Universal Orchestrator
Expand Down Expand Up @@ -69,7 +70,7 @@ Select the exported .cer file and complete the wizard
If PMP is running on the same machine as the extension and you are connecting via localhost, the certificate's hostname will not match. This is expected and is handled automatically by the extension; no additional configuration is required.

## Support
The Password Manager Pro Pam Provider is open source and there is **no SLA**. Keyfactor will address issues as resources become available. Keyfactor customers may request escalation by opening up a support ticket through their Keyfactor representative.
The Password Manager Pro Pam Provider is supported by Keyfactor for Keyfactor customers. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com.

> To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab.

Expand Down Expand Up @@ -105,7 +106,7 @@ Create the required PAM Types in the connected Command platform.

```shell
# Password-Manager-Pro
kfutil pam-types create -r password-manager-pro -n Password-Manager-Pro
kfutil pam-types create -r password-manager-pro-pam -n Password-Manager-Pro
```

##### Using the API
Expand Down
3 changes: 2 additions & 1 deletion docsource/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ The Password Manager Pro PAM Provider allows for the retrieval of stored account

## Installation and Configuration
#### In ManageEngine Password Manager Pro
When configuring ManageEngine Password Manager Pro (PMP) for use as a PAM Provider with Keyfactor, you will need to create an API user and generate an API token with the appropriate permissions. Navigate to Users → Add User → Add Api user in the PMP web interface to create the user and token. Ensure the associated user account has at minimum read access to the resources you intend to retrieve credentials from, and the host name field is set to the ip of your KeyFactor Command instance.
When configuring ManageEngine Password Manager Pro (PMP) for use as a PAM Provider with Keyfactor, you will need to create an API user and generate an API token with the appropriate permissions. Navigate to Users → Add User → Add Api user in the PMP web interface to create the user and token. Ensure the associated user account has at minimum read access to the resources you intend to retrieve credentials from, and the host name field is set to the IP of your Keyfactor Command instance.

After ensuring the API User exists and has access to the resource and account you wish to retrieve from PMP, you can use the resource's name (the "Resource Name") and the account name (the "Account Name") to retrieve credentials via the PMP PAM Provider extension.

#### On the Universal Orchestrator
Expand Down
10 changes: 5 additions & 5 deletions integration-manifest.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"$schema": "https://keyfactor.github.io/integration-manifest-schema.json",
"integration_type": "pam",
"$schema": "https://keyfactor.github.io/v2/integration-manifest-schema.json",
"name": "Password Manager Pro Pam Provider",
"status": "prototype",
"integration_type": "pam",
"status": "production",
"description": "The Password Manager Pro PAM extension allows for the retrieval of account usernames and passwords",
"support_level": "kf-community",
"support_level": "kf-supported",
"link_github": true,
"update_catalog": true,
"release_dir": "password-manager-pro-pam/bin/Release",
Expand Down Expand Up @@ -61,4 +61,4 @@
}
}
}
}
}
25 changes: 25 additions & 0 deletions password-manager-pro-pam.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31515.178
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "password-manager-pro-pam", "password-manager-pro-pam\password-manager-pro-pam.csproj", "{00AF414E-AB66-42F6-9D02-597AB6A0DF63}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{00AF414E-AB66-42F6-9D02-597AB6A0DF63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{00AF414E-AB66-42F6-9D02-597AB6A0DF63}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00AF414E-AB66-42F6-9D02-597AB6A0DF63}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00AF414E-AB66-42F6-9D02-597AB6A0DF63}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {924718C4-B817-479F-B799-87E6F1A6863C}
EndGlobalSection
EndGlobal
3 changes: 3 additions & 0 deletions password-manager-pro-pam.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<Solution>
<Project Path="paswpassword-manager-pro-pam/password-manager-pro-pam.csproj" />
</Solution>
42 changes: 19 additions & 23 deletions password-manager-pro-pam/PasswordManagerAPI.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023 Keyfactor
// Copyright 2026 Keyfactor
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -28,16 +28,14 @@ namespace Keyfactor.Extensions.Pam.PasswordManagerPro
{
internal class PasswordManagerAPI
{
internal static string GetResourceAccountID(string name, Dictionary<string, string> instanceParameters, Uri host, string Authtoken)
internal static AccountResourceLookup GetResourceAccountID(string name, Dictionary<string, string> instanceParameters, Uri host, string Authtoken)
{
ILogger logger = LogHandler.GetClassLogger<PasswordManagerAPI>();
logger.LogDebug($"PAM Provider {name} - Bazinga.");
logger.LogDebug($"PAM Provider {name} - Getting resource and account ids.");

HttpWebRequest req = (HttpWebRequest)WebRequest.Create($"{host}restapi/json/v1/resources/getResourceIdAccountId?RESOURCENAME={instanceParameters["resourceName"]}&ACCOUNTNAME={instanceParameters["accountName"]}");
req.Method = "GET";
req.Headers.Add("AUTHTOKEN", Authtoken);
//req.Headers.Add("RESOURCENAME", instanceParameters["resourceName"]);
//req.Headers.Add("ACCOUNTNAME", instanceParameters["accountName"]);
logger.LogDebug($"PAM Provider {name} - requesting secret located at {req.RequestUri}");

req.ServerCertificateValidationCallback = (sender, cert, chain, errors) =>
Expand All @@ -46,14 +44,6 @@ internal static string GetResourceAccountID(string name, Dictionary<string, stri
return filtered == System.Net.Security.SslPolicyErrors.None;
};

/*logger.LogDebug($"Request URI: {req.RequestUri}");
logger.LogDebug($"Method: {req.Method}");
logger.LogDebug($"Host header: {req.Host}");
foreach (string key in req.Headers.AllKeys)
{
logger.LogDebug($"Header: {key} = {req.Headers[key]}");
}*/

Stream responseStream;
try
{
Expand All @@ -65,7 +55,7 @@ internal static string GetResourceAccountID(string name, Dictionary<string, stri
{
Exception current = ex;
int depth = 0;
while (current != null)
while (current != null && depth <= 4)
{
logger.LogError($"Exception[{depth}]: {current.GetType().Name}: {current.Message}");
current = current.InnerException;
Expand All @@ -81,24 +71,25 @@ internal static string GetResourceAccountID(string name, Dictionary<string, stri
PMPResourceAccountResponse response = JsonConvert.DeserializeObject<PMPResourceAccountResponse>(strResponse);

if (response.Operation.Result.Status != "Success")
throw new Exception($"PAM Provider {name} - PMP API error: {response.Operation.Result.Message}");
throw new PasswordManagerProException($"PAM Provider {name} - PMP API error: {response.Operation.Result.Message}");

string resourceId = response.Operation.Details["RESOURCEID"];
string accountId = response.Operation.Details["ACCOUNTID"];
AccountResourceLookup accountResources = new AccountResourceLookup();

logger.LogDebug($"PAM Provider {name} - resolved RESOURCEID and ACCOUNTID");
return $"{resourceId},{accountId}";
accountResources.ResourceId = response.Operation.Details["RESOURCEID"];
accountResources.AccountId = response.Operation.Details["ACCOUNTID"];

logger.LogDebug($"PAM Provider {name} - resolved RESOURCEID: {accountResources.ResourceId} and ACCOUNTID: {accountResources.AccountId}");
return accountResources;
}

internal static string GetPasswordManagerValue(string name, Dictionary<string, string> instanceParameters, Uri host, string Authtoken)
{
ILogger logger = LogHandler.GetClassLogger<PasswordManagerAPI>();
logger.LogDebug($"PAM Provider {name} - Beginning secret fetch.");

string idString = GetResourceAccountID(name, instanceParameters, host, Authtoken);
string[] ids = idString.Split(',');
AccountResourceLookup accountIds = GetResourceAccountID(name, instanceParameters, host, Authtoken);

HttpWebRequest req = (HttpWebRequest)WebRequest.Create($"{host}restapi/json/v1/resources/{ids[0]}/accounts/{ids[1]}/password");
HttpWebRequest req = (HttpWebRequest)WebRequest.Create($"{host}restapi/json/v1/resources/{accountIds.ResourceId}/accounts/{accountIds.AccountId}/password");
req.Method = "GET";
req.Headers.Add("AUTHTOKEN", Authtoken);
logger.LogDebug($"PAM Provider {name} - requesting secret located at {req.RequestUri}");
Expand All @@ -120,7 +111,7 @@ internal static string GetPasswordManagerValue(string name, Dictionary<string, s
{
Exception current = ex;
int depth = 0;
while (current != null)
while (current != null && depth <= 4)
{
logger.LogError($"Exception[{depth}]: {current.GetType().Name}: {current.Message}");
current = current.InnerException;
Expand All @@ -142,6 +133,11 @@ internal static string GetPasswordManagerValue(string name, Dictionary<string, s
return response.Operation.Details["PASSWORD"];
}
}
public class AccountResourceLookup
{
public string ResourceId { get; set; }
public string AccountId { get; set; }
}
internal class PMPResourceAccountResponse
{
[JsonProperty("operation")]
Expand Down
19 changes: 12 additions & 7 deletions password-manager-pro-pam/PasswordProPam.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2023 Keyfactor
// Copyright 2026 Keyfactor
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -24,28 +24,33 @@

namespace Keyfactor.Extensions.Pam.PasswordManagerPro
{
public class PasswordManagerProException : Exception
{
public PasswordManagerProException(string msg) : base(msg) { }
}
public class PasswordManagerPAM : IPAMProvider
{
public string Name => "Password-Manager-Pro";

public string GetPassword(Dictionary<string, string> instanceParameters, Dictionary<string, string> initializationInfo)
{
ILogger logger = LogHandler.GetClassLogger<PasswordManagerPAM>();
logger.LogDebug("Password Manager Pro Starting");
logger.MethodEntry(LogLevel.Trace);
if (instanceParameters["LookupType"].Equals("Username"))
logger.LogDebug("Password Manager Pro Starting");
string lookupType = instanceParameters["LookupType"].Trim();
if (lookupType.Equals("username", StringComparison.OrdinalIgnoreCase))
{
logger.LogDebug($"Returning: {instanceParameters["accountName"]}");
logger.LogDebug("Returning Username");
return instanceParameters["accountName"];
}
else if (instanceParameters["LookupType"].Equals("Password"))
else if (lookupType.Equals("password", StringComparison.OrdinalIgnoreCase))
{
return PasswordManagerAPI.GetPasswordManagerValue(Name, instanceParameters, new Uri(initializationInfo["Host"]), initializationInfo["Authtoken"]);
}
else
{
logger.LogError("PAM extension Lookup type parameter must be defined. Options: Username, Password");
return "NULL";
logger.LogError($"PAM extension Lookup type {instanceParameters["LookupType"]} is invalid. Options: Username, Password");
throw new PasswordManagerProException($"PAM extension Lookup type {instanceParameters["LookupType"]} is invalid. Options: Username, Password");
}
}
}
Expand Down
3 changes: 0 additions & 3 deletions password-manager-pro-pam/password-manager-pro-pam.slnx

This file was deleted.

Loading