The following example shows a simple plugin that can return both passwords and private keys based on usernames:
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:
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
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:
Other than these prerequisites, the contents of the file are not restricted in any way.
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.
© 2024 One Identity LLC. ALL RIGHTS RESERVED. Terms of Use Privacy Cookie Preference Center