]> Frank Brehm's Git Trees - pixelpark/pp-admin-tools.git/commitdiff
Adding bin/mkldappasswd and its application module pp_admintools.app.mk_ldap_passwd
authorFrank Brehm <frank@brehm-online.com>
Fri, 11 Nov 2022 15:38:27 +0000 (16:38 +0100)
committerFrank Brehm <frank@brehm-online.com>
Fri, 11 Nov 2022 15:38:27 +0000 (16:38 +0100)
bin/mkldappasswd [new file with mode: 0755]
lib/pp_admintools/app/mk_ldap_passwd.py [new file with mode: 0644]

diff --git a/bin/mkldappasswd b/bin/mkldappasswd
new file mode 100755 (executable)
index 0000000..255a54b
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/bin/env python3
+
+from __future__ import print_function
+
+# Standard modules
+import sys
+
+__exp_py_version_major__ = 3
+__min_py_version_minor__ = 6
+
+if sys.version_info[0] != __exp_py_version_major__:
+    print("This script is intended to use with Python {}.".format(
+        __exp_py_version_major__), file=sys.stderr)
+    print("You are using Python: {0}.{1}.{2}-{3}-{4}.".format(
+        *sys.version_info) + "\n", file=sys.stderr)
+    sys.exit(1)
+
+if sys.version_info[1] < __min_py_version_minor__:
+    print("A minimal Python version of {maj}.{min} is necessary to execute this script.".format(
+        maj=__exp_py_version_major__, min=__min_py_version_minor__), file=sys.stderr)
+    print("You are using Python: {0}.{1}.{2}-{3}-{4}.".format(
+        *sys.version_info) + "\n", file=sys.stderr)
+    sys.exit(1)
+
+# Standard modules
+import os
+import locale
+
+try:
+    from pathlib import Path
+except ImportError:
+    from pathlib2 import Path
+
+__author__ = 'Frank Brehm <frank.brehm@pixelpark.com>'
+__copyright__ = '(C) 2022 by Frank Brehm, Digitas Pixelpark GmbH, Berlin'
+
+# own modules:
+
+my_path = Path(__file__)
+my_real_path = my_path.resolve()
+bin_path = my_real_path.parent
+base_dir = bin_path.parent
+lib_dir = base_dir.joinpath('lib')
+module_dir = lib_dir.joinpath('pp_admintools')
+
+if module_dir.exists():
+    sys.path.insert(0, str(lib_dir))
+
+from pp_admintools.app.mk_ldap_passwd import MkLdapPasswdApplication
+
+appname = os.path.basename(sys.argv[0])
+
+locale.setlocale(locale.LC_ALL, '')
+
+app = MkLdapPasswdApplication(appname=appname, base_dir=base_dir)
+app.initialized = True
+
+if app.verbose > 2:
+    print("{c}-Object:\n{a}".format(c=app.__class__.__name__, a=app))
+
+app()
+
+sys.exit(0)
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4
diff --git a/lib/pp_admintools/app/mk_ldap_passwd.py b/lib/pp_admintools/app/mk_ldap_passwd.py
new file mode 100644 (file)
index 0000000..bf34fa7
--- /dev/null
@@ -0,0 +1,228 @@
+# -*- coding: utf-8 -*-
+"""
+@summary: An application module for the mkldappasswd application
+
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2022 by Frank Brehm, Berlin
+"""
+from __future__ import absolute_import
+
+# Standard modules
+import logging
+import os
+import getpass
+import sys
+
+# Own modules
+# from fb_tools.common import to_bool, is_sequence, pp
+from fb_tools.common import is_sequence
+from fb_tools.app import BaseApplication
+
+from .. import pp
+
+from ..xlate import XLATOR
+
+from ..errors import PpAppError
+
+from .ldap import PasswordFileOptionAction
+
+from ..handler.ldap_password import WrongPwdSchemaError
+from ..handler.ldap_password import LdapPasswordHandler
+from ..handler.ldap_password import HAS_CRACKLIB
+from ..handler.ldap_password import WrongSaltError, WrongRoundsError
+
+__version__ = '0.1.1'
+LOG = logging.getLogger(__name__)
+
+_ = XLATOR.gettext
+ngettext = XLATOR.ngettext
+
+
+# =============================================================================
+class MkLdapPasswdError(PpAppError):
+    """Special exception class for exceptions inside this module."""
+
+    pass
+
+
+# =============================================================================
+class MkLdapPasswdApplication(BaseApplication):
+    """Application class for the mkldappasswd application."""
+
+    show_simulate_option = False
+
+    # -------------------------------------------------------------------------
+    def __init__(self, appname=None, base_dir=None):
+
+        LdapPasswordHandler.init_pass_schemes()
+
+        self.password = None
+        self.no_cracklib = False
+
+        self.pwd_handler = LdapPasswordHandler(
+            appname=appname, base_dir=base_dir, initialized=False)
+
+        desc = _("Encrypting the password with a defined password schema.")
+
+        super(MkLdapPasswdApplication, self).__init__(
+            appname=appname, description=desc, base_dir=base_dir, initialized=False)
+
+        self.initialized = True
+
+    # -------------------------------------------------------------------------
+    def as_dict(self, short=True):
+        """
+        Transforms the elements of the object into a dict
+
+        @param short: don't include local properties in resulting dict.
+        @type short: bool
+
+        @return: structure as dict
+        @rtype:  dict
+        """
+
+        res = super(MkLdapPasswdApplication, self).as_dict(short=short)
+
+        if self.password and self.verbose < 5:
+            res['password'] = '******'
+
+        return res
+
+    # -------------------------------------------------------------------------
+    def init_arg_parser(self):
+
+        app_group = self.arg_parser.add_argument_group(_("Options for {}").format(
+            self.appname))
+
+        schema_list = []
+        def_schema = ''
+        for method in LdapPasswordHandler.available_schemes:
+            schema_id = LdapPasswordHandler.schema_ids[method]
+            schema_list.append(schema_id)
+            if method == LdapPasswordHandler.default_schema:
+                def_schema = schema_id
+        schema_list.append('list')
+        schema_list.append('help')
+
+        help_txt = _(
+            "The schema (hashing method) to use to hash the new password. "
+            "Default: {default!r}.").format(default=def_schema)
+
+        app_group.add_argument(
+            '-m', '--method', metavar=_("TYPE"), dest="method", choices=schema_list, help=help_txt)
+
+        pwd_group = app_group.add_mutually_exclusive_group()
+
+        pwd_group.add_argument(
+            '--stdin', action="store_true", dest="stdin",
+            help=_("Like {}").format('--password-fd=0')
+        )
+
+        app_group.add_argument(
+            '-S', '--salt', metavar='SALT', dest="salt",
+            help=_(
+                "A possible salt to use on hashing the password. Caution: "
+                "not all hashing schemes are supporting a salt.")
+        )
+
+        app_group.add_argument(
+            '-R', '--rounds', metavar=_('NUMBER'), dest="rounds", type=int,
+            help=_(
+                "The number of calculation rounds to use on hashing the password. Caution: "
+                "not all hashing schemes are supporting calculation rounds.")
+        )
+
+        pwd_help = _(
+            "The password to hash. If not given and no file desriptor was given, "
+            "then the password will be requested on TTY.")
+        pwd_group.add_argument(
+            'password', metavar=_('PASSWORD'), nargs='?', help=pwd_help)
+
+        super(MkLdapPasswdApplication, self).init_arg_parser()
+
+    # -------------------------------------------------------------------------
+    def post_init(self):
+        """
+        Method to execute before calling run().
+        """
+
+        super(MkLdapPasswdApplication, self).post_init()
+
+        if self.verbose > 1:
+            msg = "Given args:\n" + pp(self.args.__dict__)
+            LOG.debug(msg)
+
+        self.pwd_handler.verbose = self.verbose
+        self.pwd_handler.simulate = self.simulate
+        self.pwd_handler.force = self.force
+        self.pwd_handler.terminal_has_colors = self.terminal_has_colors
+        self.pwd_handler.initialized = True
+
+        given_schema = getattr(self.args, 'method', None)
+        if given_schema:
+            if given_schema in ('list', 'help'):
+                self.pwd_handler.show_hashing_schemes()
+                self.exit(0)
+                return
+            try:
+                self.pwd_handler.set_schema_by_id(given_schema)
+            except WrongPwdSchemaError as e:
+                self.exit(5, str(e))
+
+        if self.args.password:
+            self.password = self.args.password
+
+    # -------------------------------------------------------------------------
+    def pre_run(self):
+
+        if not self.password:
+
+            if self.args.stdin:
+                pwd = sys.stdin.read()
+                pwd = pwd.rstrip('\r\n')
+                if pwd:
+                    self.password = pwd
+                else:
+                    msg = _("Got no password by {}.").format('STDIN')
+                    self.exit(1, msg)
+            else:
+                first_prompt = _("Password:") + ' '
+                second_prompt = _('Repeat password:') + ' '
+                self.password = self.get_password(
+                    first_prompt, second_prompt, may_empty=False, repeat=False)
+
+        super(MkLdapPasswdApplication, self).pre_run()
+
+    # -------------------------------------------------------------------------
+    def _run(self):
+
+        self.show_password()
+
+    # -------------------------------------------------------------------------
+    def show_password(self):
+
+        msg = _("Encrypting password with hashing schema '{schema}' ...").format(
+            schema=self.colored(self.pwd_handler.schema_id, 'CYAN'))
+        LOG.debug(msg)
+
+        salt = getattr(self.args, 'salt', None)
+        rounds = getattr(self.args, 'rounds', None)
+
+        LOG.debug(_("Used schema: {!r}.").format(self.pwd_handler.schema))
+        try:
+            hashed_passwd = self.pwd_handler.get_hash(
+                self.password, self.pwd_handler.schema, salt=salt, rounds=rounds)
+        except (WrongSaltError, WrongRoundsError) as e:
+            self.exit(1, str(e))
+        print(hashed_passwd)
+
+
+# =============================================================================
+if __name__ == "__main__":
+
+    pass
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list