Chat now with support
Chat with Support

One Identity Safeguard for Privileged Sessions 6.9.3 - Creating custom Credential Store plugins

Plugin modification examples

The following example shows a simple plugin that can return both passwords and private keys based on usernames:

Example: return passwords and username-based private keys
class Plugin(object):
    passdb = {
        "user": ["password"],
    }
    privkeydb = {
        "user1": [('ssh-rsa', """
-----BEGIN RSA PRIVATE KEY-----
ISNFNFIASNFIANSFINSDIIISLLERfEJW++SppInNHlL89wTymILaxgln7FfQ2vr6
aBHymY/+Xwf08GiuLg2hFmfLNGZlJNnF9YB4+3o7MfjPDZJR1ne8Vr9hkte/SuK2
OhZbAeWbxHLsdOv0+ZCm7h5/nEM1gj4va+uKgpShVbxqEH7RglyUDvKUgQ7KwUZE
GW+RPApnXFN3OVjFdAqOpzeayH0kA52A3W/ske81JFGEHvfP54EePJx1qncJAX1z
jFPllYjPlMSLujbH7sabL0+LbnZDfMxOw2NXwnaKPgVlJ7I7YQDE11NLhiWbC2f1
pTLIerTOG9lovC3caa7TaIRs8VfZLjjNXWnS5wIDAQABAoIBAB6HLgz5eXIFT+ai
ISNFNFIASNFIANSFINSDIIISLLERfEJW++SppInNHlL89wTymILaxgln7FfQ2vr6
QScd2MYvJ9dIdumxbk5dK7+5I3fGHroXTRgUF6AIKI2FCsnQtDyTY1mjZ99+dGjH
AjOKnIbKPuaj+Mpx3dLhlhDgi+DncGSizhOtb3jK1tq++YLoA7W/7n9av5Ybz8c0
iqF0WUwcd6KYphuL9583OPP6Gv33Br4jP729EkqXnJa8PcniX8y3ZlFcVmxOGqnL
ISNFNFIASNFIANSFINSDIIISLLERfEJW++SppInNHlL89wTymILaxgln7FfQ2vr6
UumxiQECgYEA9yPcGBo/R/2IyjyKBXjYcd/1u0kYZRWvloahjNoWQjs/EHvbBMlM
xmtowOHbbEg4BgymPmVR8Ux24B3XJR6SbAPMF15wJ7oD1WwG8djQSw0RrbuPgP4s
OJnRpCn4blpa15n5qUF8wCwnEJow+UUaYY1znMlmAyeWjaK1VHV7tEUCgYEA8MH1
guHR+hHyZcLTT2+QTuL2Pu2MrwLhXNz5hPcCRH72dKBdfrvpRwLKj3XJKBK4r4gN
hByiT2sJKCNks4LkyOlWQtd0khRuan/xkliH7a6Fcx+d5odQsZrRbrjpsUQFlnTB
AFv6kSnhAtmJVDalYWfPSQCuE0nwB9TaDU6UGzsCgYAItvwA4ZQPrtIPB5l6XeuM
ISNFNFIASNFIANSFINSDIIISLLERfEJW++SppInNHlL89wTymILaxgln7FfQ2vr6
QDIHNO5RiE6wTPHlv1aA/wH7lVyXGN9oU4w/9Lbs9US0y5oxLL0Abc4m2LkXYSdv
ISNFNFIASNFIANSFINSDIIISLLERfEJW++SppInNHlL89wTymILaxgln7FfQ2vr6
FykNgS4dhrCG3NmpP4zQbKnS+VDQrLJ/qbSG59Ida8nIs74yanQX17EPuzqD/iJT
LoahB2128G7BiEfcIpFVCgI0OqikYQkM4oOQD3sUw8ySfi/rZMxGtT34uf7398FH
bBRnAoGBANRNw9oTcSh/ScLNqhB1pld81UX8jf+4+9hj9U+gpQCkujVxTs7xil8R
ISNFNFIASNFIANSFINSDIIISLLERfEJW++SppInNHlL89wTymILaxgln7FfQ2vr6
31nME0D1kojABIMeW8cITVHx4PD7I8jp+3sIPRXzCr8bfTzGSOAA
-----END RSA PRIVATE KEY-----
""")],
    }
    def get_private_key_list(self, session_id, cookie, protocol, client_ip,
                            gateway_username, gateway_password,
                            target_username, target_host, target_port,
                            target_domain=None, gateway_domain=None, 
                            gateway_groups=None):
        keylist = []
        if target_username in self.privkeydb:
            keylist = self.privkeydb[target_username]
            print "Retrieved private keys;"
            print keylist
        else:
            print "User not found;"
        return {
            "private_keys": keylist,
        }
    def get_password_list(self, session_id, cookie, protocol, client_ip,
                        gateway_username, gateway_password,
                        target_username, target_host, target_port,
                        target_domain=None, gateway_domain=None
                        gateway_groups=None):
        pwlist = []
        if target_username in self.passdb:
            pwlist = self.passdb[target_username]
            print "Retrieved passwords;"
        else:
            print "User not found;"
        return {
            "passwords": pwlist,
        }
    def authentication_completed(self, session_id, cookie):
        return None
        def session_ended(self, session_id, cookie):
            return None

The following example demonstrates how the predefined hooks can be enhanced with additional logic:

Example: enhance predefined hooks
import inspect

class Plugin(object):
    passdb = {
        "joe": ["joespw1", "joespw2", ],
        "jack": ["jackspw", ],
    }

    def get_password_list(self, session_id, cookie, protocol, client_ip,
                        gateway_username, gateway_password,
                        target_username, target_host, target_port,
                        target_domain=None, gateway_domain=None, gateway_groups=None):

        # Discard "None" parameters, log all other returned parameters
        args = list(inspect.getargvalues(inspect.currentframe()).args)
        logkws = ["{arg}='{value}'".format(arg=arg, value=locals()[arg])
        for arg in args if arg != 'self' and locals()[arg] is not None]

        if "call_count" in cookie:
            call_count = cookie["call_count"]
        else:
            call_count = 0

        logkws.append("call_count='{0}'".format(call_count))

        print ("Retrieving passwords, non-null parameters follow; " + ', '.join(logkws))

        # Return the password list for the user
        pwlist = []
        if target_username in self.passdb:
            pwlist = self.passdb[target_username]
            print "Retrieved passwords;"
        else:
            print "User not found;"

        return {
            "passwords": pwlist,
            "cookie": {"call_count": call_count + 1}
        }

    def authentication_completed(self, session_id, cookie):
        call_count = cookie["call_count"] if "call_count" in cookie else None
        print ("Received notification about completed authentication; "
            "call_count='{call_count}'").format(call_count=call_count)
        return None

    def session_ended(self, session_id, cookie):
        call_count = cookie["call_count"] if "call_count" in cookie else None
        print ("Received notification about session end; "
            "call_count='{call_count}'").format(call_count=call_count)
        return None

The sample configuration file (default.cfg)

Your plugin .zip file may contain an optional default.cfg sample configuration file. This file serves to provide an example configuration that you can use as a basis for customization if you wish to adapt the plugin to your site's needs.

The only prerequisites for this file are as follows:

  • It must be a UTF-8 encoded text file.
  • The size of the file must not exceed 10 KiB.

Other than these prerequisites, the contents of the file are not restricted in any way.

Plugin troubleshooting

On the default log level, One Identity Safeguard for Privileged Sessions (SPS) logs everything that the plugin writes to stdout and stderr. Log message lines are prefixed with the session ID of the proxy, which makes it easier to find correlating messages.

To transfer information between the methods of a plugin (for example, to include data in a log message when the session is closed), you can use a cookie.

If an error occurs while executing the plugin, SPS automatically terminates the session.

NOTE: This error is not visible in the verdict of the session. To find out why the session was terminated, you have to check the logs.

Related Documents

The document was helpful.

Select Rating

I easily found the information I needed.

Select Rating