def _fn_aws_iam_list_signing_certs_function(self, event, *args, **kwargs): """Function: List the signing certificates associated with an IAM user. param aws_iam_user_name: An IAM user name. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) aws_iam_user_name = kwargs.get("aws_iam_user_name") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) validate_fields(["aws_iam_user_name"], kwargs) iam_cli = AwsIamClient(self.options) rtn = iam_cli.get("list_signing_certificates", paginate=True, **params) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_delete_login_profile_function(self, event, *args, **kwargs): """Function: Delete the password for the specified IAM user, which terminates the user's ability to access AWS services through the AWS Management Console. param aws_iam_user_name: An IAM user name. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) # Get the function parameters: aws_iam_user_name = kwargs.get("aws_iam_user_name") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) validate_fields(["aws_iam_user_name"], kwargs) iam_cli = AwsIamClient(self.options) rtn = iam_cli.post("delete_login_profile", **params) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception("ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_delete_user_function(self, event, *args, **kwargs): """Function: Delete the specified IAM user. Note: When deleting an IAM user programmatically, you must delete the items attached to the user or the deletion fails. param aws_iam_user_name: An IAM user name. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) # Get the function parameters: aws_iam_user_name = kwargs.get("aws_iam_user_name") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) validate_fields(["aws_iam_user_name"], kwargs) iam_cli = AwsIamClient(self.options) rtn = iam_cli.post("delete_user", **params) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_list_user_access_key_ids_function(self, event, *args, **kwargs): """Function: Get information about the access key IDs associated with the specified IAM user. param aws_iam_user_name: An IAM user name. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) # Get the function parameters: aws_iam_user_name = kwargs.get("aws_iam_user_name") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) validate_fields(["aws_iam_user_name"], kwargs) iam_cli = AwsIamClient(self.options) rtn = iam_cli.get("list_access_keys", paginate=True, **params) for j in range(len(rtn)): rtn[j]["key_last_used"] = \ iam_cli.get("get_access_key_last_used", AccessKeyId=rtn[j]['AccessKeyId']) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_update_access_key_function(self, event, *args, **kwargs): """Function: Update status of an IAM user access key. Change the status of an access key from Active to Inactive, or vice versa. param aws_iam_user_name: An IAM user name. param aws_iam_access_key_id: An IAM user access key id. param aws_iam_status: An IAM user access key taget status. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) # Get the function parameters: aws_iam_user_name = kwargs.get("aws_iam_user_name") # text aws_iam_access_key_id = kwargs.get("aws_iam_access_key_id") # text aws_iam_status = \ self.get_select_param(kwargs.get("aws_iam_status")) # select, values: "Active", "Inactive" LOG.info("aws_iam_user_name: %s", aws_iam_user_name) LOG.info("aws_iam_access_key_id: %s", aws_iam_access_key_id) LOG.info("aws_iam_status: %s", aws_iam_status) validate_fields(["aws_iam_user_name", "aws_iam_access_key_id", "aws_iam_status"], kwargs) iam_cli = AwsIamClient(self.options) rtn = iam_cli.post("update_access_key", **params) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception("ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_deactivate_mfa_devices_function(self, event, *args, **kwargs): """Function: Deactivate an MFA device and remove it from association with the user name for which it was originally enabled. param aws_iam_user_name: An IAM user name. param aws_iam_mfa_serial_numbers: A comma separated list of IAM MFA serial numbers or arns. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) aws_iam_user_name = kwargs.get("aws_iam_user_name") # text aws_iam_mfa_serial_nums = kwargs.get( "aws_iam_mfa_serial_nums") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) LOG.info("aws_iam_mfa_serial_nums: %s", aws_iam_mfa_serial_nums) validate_fields(["aws_iam_user_name", "aws_iam_mfa_serial_nums"], kwargs) iam_cli = AwsIamClient(self.options) # Delete 'MfaSerialNums' parameter from params. if "MfaSerialNums" in params: del params["MfaSerialNums"] rtn = [] # Iterate over mfa serial numbers in the comma separated list in parameter # 'param aws_iam_mfa_serial_numbers'. Add each in turn to the 'params' dict then attempt to deactivate each # mfa for the user in parameter 'aws_iam_user_name'. Include the status of each attempt in the returned # result. for mfa_ser_num in re.split(r"\s*,\s*", aws_iam_mfa_serial_nums): params.update({"SerialNumber": mfa_ser_num}) rtn.append({ "SerialNumber": mfa_ser_num, "Status": iam_cli.post("deactivate_mfa_device", **params) }) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_delete_ssh_keys_function(self, event, *args, **kwargs): """Function: Delete Secure Shell (SSH) public keys associated with the specified IAM user. param aws_iam_user_name: An IAM user name. aws_iam_ssh_key_ids: A comma separated list of SSH key ids credential ids. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) aws_iam_user_name = kwargs.get("aws_iam_user_name") # text aws_iam_ssh_key_ids = kwargs.get("aws_iam_ssh_key_ids") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) LOG.info("aws_iam_ssh_key_ids: %s", aws_iam_ssh_key_ids) validate_fields(["aws_iam_user_name", "aws_iam_ssh_key_ids"], kwargs) iam_cli = AwsIamClient(self.options) # Delete 'SshKeyIds' parameter from params. if "SshKeyIds" in params: del params["SshKeyIds"] rtn = [] # Iterate over SSH public key ids in the comma separated list in parameter 'aws_iam_ssh_key_ids'. # Add each in turn to the 'params' dict then attempt to delete each key for the user in parameter # 'aws_iam_user_name'. Include the status of each attempt in the returned result. for ssh_key_id in re.split(r"\s*,\s*", aws_iam_ssh_key_ids): params.update({"SSHPublicKeyId": ssh_key_id}) rtn.append({ "SSHPublicKeyId": ssh_key_id, "Status": iam_cli.post("delete_ssh_public_key", **params) }) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_update_login_profile_function(self, event, *args, **kwargs): """Function: Change the password for the specified IAM user. param aws_iam_user_name: An IAM user name. param aws_iam_password: A new password for an IAM user. param aws_iam_password_reset_required: A boolean value to determine whether a password reset should be required on change. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) # Get the function parameters: aws_iam_user_name = kwargs.get("aws_iam_user_name") # text aws_iam_password = kwargs.get("aws_iam_password") # text aws_iam_password_reset_required = kwargs.get( "aws_iam_password_reset_required") # boolean LOG.info("aws_iam_user_name: %s", aws_iam_user_name) # Hide password fro logger. LOG.info("aws_iam_password: %s", "***") LOG.info("aws_iam_password_reset_required: %s", aws_iam_password_reset_required) validate_fields([ "aws_iam_user_name", "aws_iam_password", "aws_iam_password_reset_required" ], kwargs) iam_cli = AwsIamClient(self.options) rtn = iam_cli.post("update_login_profile", **params) results = rp.done(True, rtn) # Hide password in result. results["inputs"]["aws_iam_password"] = "******" # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_add_user_to_groups_function(self, event, *args, **kwargs): """Function: Add the specified IAM user to the specified groups. :param aws_iam_user_name: An IAM user name. :param aws_iam_group_names: A comma separated list of IAM group names. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) # Get the function parameters: aws_iam_user_name = kwargs.get("aws_iam_user_name") # text aws_iam_group_names = kwargs.get("aws_iam_group_names") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) LOG.info("aws_iam_group_names: %s", aws_iam_group_names) validate_fields(["aws_iam_user_name", "aws_iam_group_names"], kwargs) iam_cli = AwsIamClient(self.options) # Pop 'GroupNames' parameter from params. if "GroupNames" in params: del params["GroupNames"] rtn = [] # Iterate over group names in the comma separated list in parameter 'aws_iam_group_names'. Add each in # turn to the 'params' dict then attempt to add the user in parameter 'aws_iam_user_name' to the group. # Include the status of each attempt in the returned result. for group_name in re.split(r"\s*,\s*", aws_iam_group_names): params.update({"GroupName": group_name}) rtn.append({ "GroupName": group_name, "Status": iam_cli.post("add_user_to_group", **params)} ) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception("ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_list_mfa_devices_function(self, event, *args, **kwargs): """Function: List the MFA devices associated with an IAM user also determine which of the associated MFA devices is a virtual device. param aws_iam_user_name: An IAM user name. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) aws_iam_user_name = kwargs.get("aws_iam_user_name") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) validate_fields(["aws_iam_user_name"], kwargs) iam_cli = AwsIamClient(self.options) # Get active mfa devices for user. rtn = iam_cli.get("list_mfa_devices", paginate=True, **params) if isinstance(rtn, list): # Get virtual mfa devices for the account. virt_mfas = iam_cli.get("list_virtual_mfa_devices", paginate=True) # Determine if active mfa is also a virtual MFA. for i in range(len(rtn)): for virt_mfa in virt_mfas: if rtn[i]["SerialNumber"] == virt_mfa["SerialNumber"]: rtn[i]["is_virtual"] = True results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_list_user_policies_function(self, event, *args, **kwargs): """Function: Get all managed policies and in-line policies that are attached to the specified IAM user. param aws_iam_user_name: An IAM user name. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) # Get the function parameters: aws_iam_user_name = kwargs.get("aws_iam_user_name") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) validate_fields(["aws_iam_user_name"], kwargs) iam_cli = AwsIamClient(self.options) # Get user managed policies. rtn = iam_cli.get("list_attached_user_policies", paginate=True, **params) # Add user in-line policies at beginning of result. for user_policy in iam_cli.get("list_user_policies", paginate=True, **params): rtn[:0] = [user_policy] results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def selftest_function(opts): """ Simple test to verify AWS IAM connectivity. """ options = opts.get("fn_aws_iam", {}) try: iam = AwsIamClient(options, sts_client=True) default_identity = iam.sts.get_caller_identity() if isinstance(default_identity, dict) and "Arn" in default_identity: user_name = default_identity["Arn"].split('/')[1] user_properties = iam.iam.get_user(UserName=user_name) if isinstance(user_properties, dict) and "User" in user_properties: return {"state": "success"} else: return {"state": "failure"} else: return {"state": "failure"} except Exception as e: return {"state": "failure", "status_code": e}
def _fn_aws_iam_detach_user_policies_function(self, event, *args, **kwargs): """Function: Remove the specified managed policy from the specified IAM user. Note: A user can also have inline policies embedded with it, this function will delete inline policies associated with the the user. Parameter aws_iam_user_name is an IAM user name. Note: one of parameters aws_iam_policy_names or aws_iam_arns required to be set. param aws_iam_policy_names: (optional) A comma separated list of IAM policy names. param aws_iam_arns: (optional) A comma separated list of IAM policy arns. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) # Get the function parameters: aws_iam_user_name = kwargs.get("aws_iam_user_name") # text aws_iam_policy_names = kwargs.get("aws_iam_policy_names") # text aws_iam_arns = kwargs.get("aws_iam_arns") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) LOG.info("aws_iam_policy_names: %s", aws_iam_policy_names) LOG.info("aws_iam_arns: %s", aws_iam_arns) if not aws_iam_policy_names and not aws_iam_arns: raise ValueError( "Expected either parameter '{0}' or '{1}' to be set.". format("aws_iam_policy_names", "aws_iam_arns")) if all([aws_iam_policy_names, aws_iam_arns]): raise ValueError( "Expected only one of parameters '{0}' or '{1}' to be set." .format("aws_iam_policy_names", "aws_iam_arns")) iam_cli = AwsIamClient(self.options) rtn = [] if aws_iam_policy_names: # Delete 'PolicyNames' from params del params["PolicyNames"] # Get user policies user_policies = iam_cli.get("list_attached_user_policies", paginate=True, UserName=aws_iam_user_name) inline_policies = iam_cli.get("list_user_policies", paginate=True, UserName=aws_iam_user_name) # Iterate over policy names in the comma separated list in parameter 'aws_iam_policy_names'. Add each # in turn to the 'params' dict then attempt to detach each policy from the user in parameter # 'aws_iam_user_name'. Include the status of each attempt in the returned result. for policy_name in re.split(r"\s*,\s*", aws_iam_policy_names): # Test if policy_name is attached for user name and get arn. if inline_policies and policy_name in [ ip["PolicyName"] for ip in inline_policies ]: if "PolicyArn" in params: # Delete 'PolicyArn' from 'params' if in-line policy. del params["PolicyArn"] # Policy is an in-line policy delete instead. params.update({"PolicyName": policy_name}) rtn.append({ "PolicyName": policy_name, "Status": iam_cli.post("delete_user_policy", **params) }) elif user_policies: if "PolicyName" in params: # Delete 'PolicyName' from 'params' if managed policy. del params["PolicyName"] # Detach managed policies instead of deleting. policy_list = [ policy for policy in user_policies if policy["PolicyName"] == policy_name ] if not user_policies or not policy_list: raise ValueError( "Policy with name '{0}' not attached for user '{1}'." .format(policy_name, aws_iam_user_name)) policy = policy_list[0] params.update({"PolicyArn": policy["PolicyArn"]}) rtn.append({ "PolicyName": policy_name, "Status": iam_cli.post("detach_user_policy", **params) }) else: # Delete 'Arn' from params del params["Arns"] # Iterate over policy arns in the comma separated list in parameter 'aws_iam_arns'. Add each in turn # to the 'params' dict then attempt to detach each policy to the user in parameter # 'aws_iam_user_name'. Include the status of each attempt in the returned result. for arn in re.split(r"\s*,\s*", aws_iam_arns): params.update({"PolicyArn": arn}) rtn.append({ "PolicyArn": arn, "Status": iam_cli.post("detach_user_policy", **params) }) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()
def _fn_aws_iam_remove_user_from_groups_function(self, event, *args, **kwargs): """Function: Removes the specified IAM user from the specified groups. Group names is be a comma separated string of group names. param aws_iam_user_name: An IAM user name. param aws_iam_group_names: A comma separated list of IAM group names. """ try: params = transform_kwargs(kwargs) if kwargs else {} # Instantiate result payload object rp = ResultPayload(CONFIG_DATA_SECTION, **kwargs) # Get the function parameters: aws_iam_user_name = kwargs.get("aws_iam_user_name") # text aws_iam_group_names = kwargs.get("aws_iam_group_names") # text LOG.info("aws_iam_user_name: %s", aws_iam_user_name) LOG.info("aws_iam_group_names: %s", aws_iam_group_names) validate_fields(["aws_iam_user_name", "aws_iam_group_names"], kwargs) iam_cli = AwsIamClient(self.options) # Pop 'GroupNames' parameter from params. if "GroupNames" in params: del params["GroupNames"] # Get user groups user_groups = iam_cli.get("list_groups_for_user", paginate=True, UserName=aws_iam_user_name) rtn = [] # Iterate over group names in the comma separated list in parameter 'aws_iam_group_names'. For each group, # if the group exists, add to the 'params' dict then attempt to remove the user in parameter # 'aws_iam_user_name' from the group. Include the status of each attempt in the returned result. for group_name in re.split(r"\s*,\s*", aws_iam_group_names): # Test that the user is a member of the group. if user_groups: group = [ group for group in user_groups if group["GroupName"] == group_name ][0] if not user_groups or not group: raise ValueError( "User '{0}' is not a member of group '{1}'.".format( aws_iam_user_name, group_name)) params.update({"GroupName": group_name}) rtn.append({ "GroupName": group_name, "Status": iam_cli.post("remove_user_from_group", **params) }) results = rp.done(True, rtn) # Produce a FunctionResult with the results yield FunctionResult(results) except Exception as aws_err: LOG.exception( "ERROR with Exception '%s' in Resilient Function for AWS IAM.", aws_err.__repr__()) yield FunctionError()