From 349f2b9dea84646dc55e1d34e957582ba427afe2 Mon Sep 17 00:00:00 2001 From: "embed@git.macaw.me" Date: Thu, 21 Dec 2023 10:52:30 +0000 Subject: [PATCH] first --- library/ansible-keepassxc | 189 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100755 library/ansible-keepassxc diff --git a/library/ansible-keepassxc b/library/ansible-keepassxc new file mode 100755 index 0000000..ef391be --- /dev/null +++ b/library/ansible-keepassxc @@ -0,0 +1,189 @@ +#!/usr/bin/python + +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +import os +import traceback +from ansible.module_utils.basic import AnsibleModule, missing_required_lib + +IMPORT_ERR = None +try: +# import _argon2_xffi_bindings + import pykeepass as keepass +except ImportError: + IMPORT_ERR = traceback.format_exc() + +DOCUMENTATION = r''' +--- +module: ansible-keepassxc + +short_description: Module to read credentials from KeePassXC + +version_added: "0.0.1" + +description: Module to read credentials from KeePassXC + +options: + database: + description: Path to database file + required: true + type: str + password: + description: Database Password + required: true + type: str + keyfile: + description: Path to key file + required: false + type: str + entry: + description: Entry name for the attribute to fetch + required: true + type: str + group: + decription: Group name that the Entry belongs to + required: false + type: str + +author: + - Jeremy Lumley (@jlumley) +''' + +EXAMPLES = r''' +# Fetch the credentials for the server_1 entry in any group +- name: Fetch server_1 credentials + jlumley.jlumley.ansible-keepassxc: + database: "/secrets/db.kdbx" + password: "s3cure_p4550rd" + entry: "server_1" + +# Fetch the reddit entry in the social group +- name: Fetching reddit credentials + jlumley.jlumley.ansible-keepassxc: + database: "/secrets/db.kdbx" + password: "sup3r_s3cure_p4550rd" + entry: "reddit" + group: "social" + +# Fetch a custom strig attribute from the github entry +- name: Fetch Github API Token + jlumley.jlumley.ansible-keepassxc: + database: "/secrets/db.kdbx" + password: "d0pe_s3cure_p4550rd" + keyfile: "/secrets/top_secret_key" + entry: "github" + group: "development" + +''' + +RETURN = r''' +# Return values +username: + description: Username of entry if present + type: str + returned: always + sample: 's3cr3t_us3r' +password: + description: Password of entry if present + type: str + returned: always + sample: 's3cr3t_p455word' +url: + description: Url of entry if present + type: str + returned: always + sample: 'http://reddit.com' +custom_fields: + description: dictionary containing all custom fields + type: dict + returned: always + sample: False +no_log: + description: suppress logging of password + type: bool + returned: never + sample: False +''' + +def run_module(): + # define available arguments/parameters a user can pass to the module + module_args = dict( + database = dict(type='str', required=True), + password = dict(type='str', required=False, + default=os.environ.get('ANSIBLE_KEEPASSXC_PASSWORD')), + keyfile = dict(type='str', required=False, default=None), + entry = dict(type='str', required=True), + group = dict(type='str', required=False), + no_log = dict(type='bool', required=False, default=False), + ) + + # seed the result dict in the object + result = dict( + changed=False, + username='', + password='', + url='', + custom_fields={} + ) + + # Currently no support for a check_mode this maybe added later if + # functionality to modify the database is added later + module = AnsibleModule( + argument_spec=module_args, + supports_check_mode=False, + ) + + if IMPORT_ERR: + module.fail_json( + msg=missing_required_lib("pykeepass"), + exception=IMPORT_ERR + ) + + # unlock local keepass database + try: + kp = keepass.PyKeePass( + module.params['database'], + password=module.params['password'], + keyfile=module.params['keyfile']) + except keepass.exceptions.CredentialsError: + module.fail_json(msg='Invalid Credentials') + + # find entry + entry = kp.find_entries( + title=module.params['entry'], + group=module.params['group'] + ) + + # fail is entry is not present + if not entry: + module.fail_json(msg=f"Unable to find entry: {module.params['entry']}") + + else: + entry = entry[0] + custom_field_keys = entry._get_string_field_keys(exclude_reserved=True) + custom_fields = dict() + for key in custom_field_keys: + custom_fields[key] = entry.get_custom_property(key) + result = dict ( + changed=False, + username=entry.username, + password=entry.password, + url=entry.url, + custom_fields=custom_fields + ) + + # in the event of a successful module execution, you will want to + # simple AnsibleModule.exit_json(), passing the key/value results + module.exit_json(**result) + + +def main(): + run_module() + + +if __name__ == '__main__': + main() + +